diff options
author | Ralf S. Engelschall <rse@openssl.org> | 1998-12-21 10:52:47 +0000 |
---|---|---|
committer | Ralf S. Engelschall <rse@openssl.org> | 1998-12-21 10:52:47 +0000 |
commit | d02b48c63a58ea4367a0e905979f140b7d090f86 (patch) | |
tree | 504f62ed3d84799f785b9cd9fab255a21b0e1b0e /crypto/bn | |
download | openssl-d02b48c63a58ea4367a0e905979f140b7d090f86.tar.gz |
Import of old SSLeay release: SSLeay 0.8.1b
Diffstat (limited to 'crypto/bn')
49 files changed, 12692 insertions, 0 deletions
diff --git a/crypto/bn/Makefile.ssl b/crypto/bn/Makefile.ssl new file mode 100644 index 0000000000..cbddd4f3ea --- /dev/null +++ b/crypto/bn/Makefile.ssl @@ -0,0 +1,107 @@ +# +# SSLeay/crypto/bn/Makefile +# + +DIR= bn +TOP= ../.. +CC= cc +INCLUDES= -I.. -I../../include +CFLAG=-g +INSTALLTOP=/usr/local/ssl +MAKE= make -f Makefile.ssl +MAKEDEPEND= makedepend -f Makefile.ssl +MAKEFILE= Makefile.ssl +BN_MULW= bn_mulw.o +AR= ar r + +CFLAGS= $(INCLUDES) $(CFLAG) + +ERR=bn +ERRC=bn_err +GENERAL=Makefile +TEST=bntest.c exptest.c +APPS= + +LIB=$(TOP)/libcrypto.a +LIBSRC= bn_add.c bn_div.c bn_exp.c bn_lib.c bn_mod.c bn_mul.c \ + bn_print.c bn_rand.c bn_shift.c bn_sub.c bn_word.c \ + bn_gcd.c bn_prime.c $(ERRC).c bn_sqr.c bn_mulw.c bn_recp.c bn_mont.c + +LIBOBJ= bn_add.o bn_div.o bn_exp.o bn_lib.o bn_mod.o bn_mul.o \ + bn_print.o bn_rand.o bn_shift.o bn_sub.o bn_word.o \ + bn_gcd.o bn_prime.o $(ERRC).o bn_sqr.o $(BN_MULW) bn_recp.o bn_mont.o + + +SRC= $(LIBSRC) + +EXHEADER= bn.h +HEADER= bn_lcl.h bn_prime.h $(EXHEADER) + +ALL= $(GENERAL) $(SRC) $(HEADER) + +top: + (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all) + +all: lib + +knuth: bn_knuth.c + cc -pg -I.. -I../../include bn_knuth.c -o knuth $(LIB) #../../../libefence.a + +knuth.fast: bn_knuth.c + cc -pg -fast -I.. -I../../include bn_knuth.c -o knuth $(LIB) #../../../libefence.a + + +lib: $(LIBOBJ) + $(AR) $(LIB) $(LIBOBJ) + sh $(TOP)/util/ranlib.sh $(LIB) + @touch lib + +files: + perl $(TOP)/util/files.pl Makefile.ssl >> $(TOP)/MINFO + +links: + /bin/rm -f Makefile + $(TOP)/util/point.sh Makefile.ssl Makefile ; + $(TOP)/util/mklink.sh ../../include $(EXHEADER) + $(TOP)/util/mklink.sh ../../test $(TEST) + $(TOP)/util/mklink.sh ../../apps $(APPS) + +install: + @for i in $(EXHEADER) ; \ + do \ + (cp $$i $(INSTALLTOP)/include/$$i; \ + chmod 644 $(INSTALLTOP)/include/$$i ); \ + done; + +exptest: + /bin/rm -f exptest + gcc -I../../include -g2 -ggdb -o exptest exptest.c ../../libcrypto.a + +div: + /bin/rm -f a.out + gcc -I.. -g div.c ../../libcrypto.a + +tags: + ctags $(SRC) + +tests: + +lint: + lint -DLINT $(INCLUDES) $(SRC)>fluff + +depend: + $(MAKEDEPEND) $(INCLUDES) $(PROGS) $(LIBSRC) + +dclean: + perl -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new + mv -f Makefile.new $(MAKEFILE) + +clean: + /bin/rm -f *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff bn_mulw.s + +errors: + perl $(TOP)/util/err-ins.pl $(ERR).err $(ERR).org # special case .org + perl $(TOP)/util/err-ins.pl $(ERR).err $(ERR).h + perl ../err/err_genc.pl $(ERR).h $(ERRC).c + +# DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/crypto/bn/asm/README b/crypto/bn/asm/README new file mode 100644 index 0000000000..d93fbff77f --- /dev/null +++ b/crypto/bn/asm/README @@ -0,0 +1,30 @@ +All assember in this directory are just version of the file +crypto/bn/bn_mulw.c. + +Quite a few of these files are just the assember output from gcc since on +quite a few machines they are 2 times faster than the system compiler. + +For the x86, I have hand written assember because of the bad job all +compilers seem to do on it. This normally gives a 2 time speed up in the RSA +routines. + +For the DEC alpha, I also hand wrote the assember (except the division which +is just the output from the C compiler pasted on the end of the file). +On the 2 alpha C compilers I had access to, it was not possible to do +64b x 64b -> 128b calculations (both long and the long long data types +were 64 bits). So the hand assember gives access to the 128 bit result and +a 2 times speedup :-). + +The x86xxxx.obj files are the assembled version of x86xxxx.asm files. +I had such a hard time finding a macro assember for Microsoft, I decided to +include the object file to save others the hassle :-). + +I have also included uu encoded versions of the .obj incase they get +trashed. + +There are 2 versions of assember for the HP PA-RISC. +pa-risc.s is the origional one which works fine. +pa-risc2.s is a new version that often generates warnings but if the +tests pass, it gives performance that is over 2 times faster than +pa-risc.s. +Both were generated using gcc :-) diff --git a/crypto/bn/asm/alpha.s b/crypto/bn/asm/alpha.s new file mode 100644 index 0000000000..d56f715ecd --- /dev/null +++ b/crypto/bn/asm/alpha.s @@ -0,0 +1,310 @@ + # DEC Alpha assember + # The bn_div64 is actually gcc output but the other parts are hand done. + # Thanks to tzeruch@ceddec.com for sending me the gcc output for + # bn_div64. + .file 1 "bn_mulw.c" + .version "01.01" + .set noat +gcc2_compiled.: +__gnu_compiled_c: + .text + .align 3 + .globl bn_mul_add_word + .ent bn_mul_add_word +bn_mul_add_word: +bn_mul_add_word..ng: + .frame $30,0,$26,0 + .prologue 0 + subq $18,2,$25 # num=-2 + bis $31,$31,$0 + blt $25,$42 + .align 5 +$142: + subq $18,2,$18 # num-=2 + subq $25,2,$25 # num-=2 + + ldq $1,0($17) # a[0] + ldq $2,8($17) # a[1] + + mulq $19,$1,$3 # a[0]*w low part r3 + umulh $19,$1,$1 # a[0]*w high part r1 + mulq $19,$2,$4 # a[1]*w low part r4 + umulh $19,$2,$2 # a[1]*w high part r2 + + ldq $22,0($16) # r[0] r22 + ldq $23,8($16) # r[1] r23 + + addq $3,$22,$3 # a0 low part + r[0] + addq $4,$23,$4 # a1 low part + r[1] + cmpult $3,$22,$5 # overflow? + cmpult $4,$23,$6 # overflow? + addq $5,$1,$1 # high part + overflow + addq $6,$2,$2 # high part + overflow + + addq $3,$0,$3 # add c + cmpult $3,$0,$5 # overflow? + stq $3,0($16) + addq $5,$1,$0 # c=high part + overflow + + addq $4,$0,$4 # add c + cmpult $4,$0,$5 # overflow? + stq $4,8($16) + addq $5,$2,$0 # c=high part + overflow + + ble $18,$43 + + addq $16,16,$16 + addq $17,16,$17 + blt $25,$42 + + br $31,$142 +$42: + ldq $1,0($17) # a[0] + umulh $19,$1,$3 # a[0]*w high part + mulq $19,$1,$1 # a[0]*w low part + ldq $2,0($16) # r[0] + addq $1,$2,$1 # low part + r[0] + cmpult $1,$2,$4 # overflow? + addq $4,$3,$3 # high part + overflow + addq $1,$0,$1 # add c + cmpult $1,$0,$4 # overflow? + addq $4,$3,$0 # c=high part + overflow + stq $1,0($16) + + .align 4 +$43: + ret $31,($26),1 + .end bn_mul_add_word + .align 3 + .globl bn_mul_word + .ent bn_mul_word +bn_mul_word: +bn_mul_word..ng: + .frame $30,0,$26,0 + .prologue 0 + subq $18,2,$25 # num=-2 + bis $31,$31,$0 + blt $25,$242 + .align 5 +$342: + subq $18,2,$18 # num-=2 + subq $25,2,$25 # num-=2 + + ldq $1,0($17) # a[0] + ldq $2,8($17) # a[1] + + mulq $19,$1,$3 # a[0]*w low part r3 + umulh $19,$1,$1 # a[0]*w high part r1 + mulq $19,$2,$4 # a[1]*w low part r4 + umulh $19,$2,$2 # a[1]*w high part r2 + + addq $3,$0,$3 # add c + cmpult $3,$0,$5 # overflow? + stq $3,0($16) + addq $5,$1,$0 # c=high part + overflow + + addq $4,$0,$4 # add c + cmpult $4,$0,$5 # overflow? + stq $4,8($16) + addq $5,$2,$0 # c=high part + overflow + + ble $18,$243 + + addq $16,16,$16 + addq $17,16,$17 + blt $25,$242 + + br $31,$342 +$242: + ldq $1,0($17) # a[0] + umulh $19,$1,$3 # a[0]*w high part + mulq $19,$1,$1 # a[0]*w low part + addq $1,$0,$1 # add c + cmpult $1,$0,$4 # overflow? + addq $4,$3,$0 # c=high part + overflow + stq $1,0($16) +$243: + ret $31,($26),1 + .end bn_mul_word + .align 3 + .globl bn_sqr_words + .ent bn_sqr_words +bn_sqr_words: +bn_sqr_words..ng: + .frame $30,0,$26,0 + .prologue 0 + + subq $18,2,$25 # num=-2 + blt $25,$442 + .align 5 +$542: + subq $18,2,$18 # num-=2 + subq $25,2,$25 # num-=2 + + ldq $1,0($17) # a[0] + ldq $4,8($17) # a[1] + + mulq $1,$1,$2 # a[0]*w low part r2 + umulh $1,$1,$3 # a[0]*w high part r3 + mulq $4,$4,$5 # a[1]*w low part r5 + umulh $4,$4,$6 # a[1]*w high part r6 + + stq $2,0($16) # r[0] + stq $3,8($16) # r[1] + stq $5,16($16) # r[3] + stq $6,24($16) # r[4] + + ble $18,$443 + + addq $16,32,$16 + addq $17,16,$17 + blt $25,$442 + br $31,$542 + +$442: + ldq $1,0($17) # a[0] + mulq $1,$1,$2 # a[0]*w low part r2 + umulh $1,$1,$3 # a[0]*w high part r3 + stq $2,0($16) # r[0] + stq $3,8($16) # r[1] + + .align 4 +$443: + ret $31,($26),1 + .end bn_sqr_words + + # + # What follows was taken directly from the C compiler with a few + # hacks to redo the lables. + # +.text + .align 3 + .globl bn_div64 + .ent bn_div64 +bn_div64: + ldgp $29,0($27) +bn_div64..ng: + lda $30,-48($30) + .frame $30,48,$26,0 + stq $26,0($30) + stq $9,8($30) + stq $10,16($30) + stq $11,24($30) + stq $12,32($30) + stq $13,40($30) + .mask 0x4003e00,-48 + .prologue 1 + bis $16,$16,$9 + bis $17,$17,$10 + bis $18,$18,$11 + bis $31,$31,$13 + bis $31,2,$12 + bne $11,$119 + lda $0,-1 + br $31,$136 + .align 4 +$119: + bis $11,$11,$16 + jsr $26,BN_num_bits_word + ldgp $29,0($26) + subq $0,64,$1 + beq $1,$120 + bis $31,1,$1 + sll $1,$0,$1 + cmpule $9,$1,$1 + bne $1,$120 + # lda $16,_IO_stderr_ + # lda $17,$C32 + # bis $0,$0,$18 + # jsr $26,fprintf + # ldgp $29,0($26) + jsr $26,abort + ldgp $29,0($26) + .align 4 +$120: + bis $31,64,$3 + cmpult $9,$11,$2 + subq $3,$0,$1 + addl $1,$31,$0 + subq $9,$11,$1 + cmoveq $2,$1,$9 + beq $0,$122 + zapnot $0,15,$2 + subq $3,$0,$1 + sll $11,$2,$11 + sll $9,$2,$3 + srl $10,$1,$1 + sll $10,$2,$10 + bis $3,$1,$9 +$122: + srl $11,32,$5 + zapnot $11,15,$6 + lda $7,-1 + .align 5 +$123: + srl $9,32,$1 + subq $1,$5,$1 + bne $1,$126 + zapnot $7,15,$27 + br $31,$127 + .align 4 +$126: + bis $9,$9,$24 + bis $5,$5,$25 + divqu $24,$25,$27 +$127: + srl $10,32,$4 + .align 5 +$128: + mulq $27,$5,$1 + subq $9,$1,$3 + zapnot $3,240,$1 + bne $1,$129 + mulq $6,$27,$2 + sll $3,32,$1 + addq $1,$4,$1 + cmpule $2,$1,$2 + bne $2,$129 + subq $27,1,$27 + br $31,$128 + .align 4 +$129: + mulq $27,$6,$1 + mulq $27,$5,$4 + srl $1,32,$3 + sll $1,32,$1 + addq $4,$3,$4 + cmpult $10,$1,$2 + subq $10,$1,$10 + addq $2,$4,$2 + cmpult $9,$2,$1 + bis $2,$2,$4 + beq $1,$134 + addq $9,$11,$9 + subq $27,1,$27 +$134: + subl $12,1,$12 + subq $9,$4,$9 + beq $12,$124 + sll $27,32,$13 + sll $9,32,$2 + srl $10,32,$1 + sll $10,32,$10 + bis $2,$1,$9 + br $31,$123 + .align 4 +$124: + bis $13,$27,$0 +$136: + ldq $26,0($30) + ldq $9,8($30) + ldq $10,16($30) + ldq $11,24($30) + ldq $12,32($30) + ldq $13,40($30) + addq $30,48,$30 + ret $31,($26),1 + .end bn_div64 + .ident "GCC: (GNU) 2.7.2.1" + + diff --git a/crypto/bn/asm/pa-risc.s b/crypto/bn/asm/pa-risc.s new file mode 100644 index 0000000000..c49c433a83 --- /dev/null +++ b/crypto/bn/asm/pa-risc.s @@ -0,0 +1,710 @@ + .SPACE $PRIVATE$ + .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31 + .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82 + .SPACE $TEXT$ + .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44 + .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY + .IMPORT $global$,DATA + .IMPORT $$dyncall,MILLICODE +; gcc_compiled.: + .SPACE $TEXT$ + .SUBSPA $CODE$ + + .align 4 + .EXPORT bn_mul_add_word,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR,RTNVAL=GR +bn_mul_add_word + .PROC + .CALLINFO FRAME=0,CALLS,SAVE_RP + .ENTRY + stw %r2,-20(0,%r30) + ldi 0,%r28 + extru %r23,31,16,%r2 + stw %r2,-16(0,%r30) + extru %r23,15,16,%r23 + ldil L'65536,%r31 + fldws -16(0,%r30),%fr11R + stw %r23,-16(0,%r30) + ldo 12(%r25),%r29 + ldo 12(%r26),%r23 + fldws -16(0,%r30),%fr11L +L$0002 + ldw 0(0,%r25),%r19 + extru %r19,31,16,%r20 + stw %r20,-16(0,%r30) + extru %r19,15,16,%r19 + fldws -16(0,%r30),%fr22L + stw %r19,-16(0,%r30) + xmpyu %fr22L,%fr11R,%fr8 + fldws -16(0,%r30),%fr22L + fstws %fr8R,-16(0,%r30) + xmpyu %fr11R,%fr22L,%fr10 + ldw -16(0,%r30),%r2 + stw %r20,-16(0,%r30) + xmpyu %fr22L,%fr11L,%fr9 + fldws -16(0,%r30),%fr22L + fstws %fr10R,-16(0,%r30) + copy %r2,%r22 + ldw -16(0,%r30),%r2 + fstws %fr9R,-16(0,%r30) + xmpyu %fr11L,%fr22L,%fr8 + copy %r2,%r19 + ldw -16(0,%r30),%r2 + fstws %fr8R,-16(0,%r30) + copy %r2,%r20 + ldw -16(0,%r30),%r2 + addl %r2,%r19,%r21 + comclr,<<= %r19,%r21,0 + addl %r20,%r31,%r20 +L$0005 + extru %r21,15,16,%r19 + addl %r20,%r19,%r20 + zdep %r21,15,16,%r19 + addl %r22,%r19,%r22 + comclr,<<= %r19,%r22,0 + addi,tr 1,%r20,%r19 + copy %r20,%r19 + addl %r22,%r28,%r20 + comclr,<<= %r28,%r20,0 + addi 1,%r19,%r19 + ldw 0(0,%r26),%r28 + addl %r20,%r28,%r20 + comclr,<<= %r28,%r20,0 + addi,tr 1,%r19,%r28 + copy %r19,%r28 + addib,= -1,%r24,L$0003 + stw %r20,0(0,%r26) + ldw -8(0,%r29),%r19 + extru %r19,31,16,%r20 + stw %r20,-16(0,%r30) + extru %r19,15,16,%r19 + fldws -16(0,%r30),%fr22L + stw %r19,-16(0,%r30) + xmpyu %fr22L,%fr11R,%fr8 + fldws -16(0,%r30),%fr22L + fstws %fr8R,-16(0,%r30) + xmpyu %fr11R,%fr22L,%fr10 + ldw -16(0,%r30),%r2 + stw %r20,-16(0,%r30) + xmpyu %fr22L,%fr11L,%fr9 + fldws -16(0,%r30),%fr22L + fstws %fr10R,-16(0,%r30) + copy %r2,%r22 + ldw -16(0,%r30),%r2 + fstws %fr9R,-16(0,%r30) + xmpyu %fr11L,%fr22L,%fr8 + copy %r2,%r19 + ldw -16(0,%r30),%r2 + fstws %fr8R,-16(0,%r30) + copy %r2,%r20 + ldw -16(0,%r30),%r2 + addl %r2,%r19,%r21 + comclr,<<= %r19,%r21,0 + addl %r20,%r31,%r20 +L$0010 + extru %r21,15,16,%r19 + addl %r20,%r19,%r20 + zdep %r21,15,16,%r19 + addl %r22,%r19,%r22 + comclr,<<= %r19,%r22,0 + addi,tr 1,%r20,%r19 + copy %r20,%r19 + addl %r22,%r28,%r20 + comclr,<<= %r28,%r20,0 + addi 1,%r19,%r19 + ldw -8(0,%r23),%r28 + addl %r20,%r28,%r20 + comclr,<<= %r28,%r20,0 + addi,tr 1,%r19,%r28 + copy %r19,%r28 + addib,= -1,%r24,L$0003 + stw %r20,-8(0,%r23) + ldw -4(0,%r29),%r19 + extru %r19,31,16,%r20 + stw %r20,-16(0,%r30) + extru %r19,15,16,%r19 + fldws -16(0,%r30),%fr22L + stw %r19,-16(0,%r30) + xmpyu %fr22L,%fr11R,%fr8 + fldws -16(0,%r30),%fr22L + fstws %fr8R,-16(0,%r30) + xmpyu %fr11R,%fr22L,%fr10 + ldw -16(0,%r30),%r2 + stw %r20,-16(0,%r30) + xmpyu %fr22L,%fr11L,%fr9 + fldws -16(0,%r30),%fr22L + fstws %fr10R,-16(0,%r30) + copy %r2,%r22 + ldw -16(0,%r30),%r2 + fstws %fr9R,-16(0,%r30) + xmpyu %fr11L,%fr22L,%fr8 + copy %r2,%r19 + ldw -16(0,%r30),%r2 + fstws %fr8R,-16(0,%r30) + copy %r2,%r20 + ldw -16(0,%r30),%r2 + addl %r2,%r19,%r21 + comclr,<<= %r19,%r21,0 + addl %r20,%r31,%r20 +L$0015 + extru %r21,15,16,%r19 + addl %r20,%r19,%r20 + zdep %r21,15,16,%r19 + addl %r22,%r19,%r22 + comclr,<<= %r19,%r22,0 + addi,tr 1,%r20,%r19 + copy %r20,%r19 + addl %r22,%r28,%r20 + comclr,<<= %r28,%r20,0 + addi 1,%r19,%r19 + ldw -4(0,%r23),%r28 + addl %r20,%r28,%r20 + comclr,<<= %r28,%r20,0 + addi,tr 1,%r19,%r28 + copy %r19,%r28 + addib,= -1,%r24,L$0003 + stw %r20,-4(0,%r23) + ldw 0(0,%r29),%r19 + extru %r19,31,16,%r20 + stw %r20,-16(0,%r30) + extru %r19,15,16,%r19 + fldws -16(0,%r30),%fr22L + stw %r19,-16(0,%r30) + xmpyu %fr22L,%fr11R,%fr8 + fldws -16(0,%r30),%fr22L + fstws %fr8R,-16(0,%r30) + xmpyu %fr11R,%fr22L,%fr10 + ldw -16(0,%r30),%r2 + stw %r20,-16(0,%r30) + xmpyu %fr22L,%fr11L,%fr9 + fldws -16(0,%r30),%fr22L + fstws %fr10R,-16(0,%r30) + copy %r2,%r22 + ldw -16(0,%r30),%r2 + fstws %fr9R,-16(0,%r30) + xmpyu %fr11L,%fr22L,%fr8 + copy %r2,%r19 + ldw -16(0,%r30),%r2 + fstws %fr8R,-16(0,%r30) + copy %r2,%r20 + ldw -16(0,%r30),%r2 + addl %r2,%r19,%r21 + comclr,<<= %r19,%r21,0 + addl %r20,%r31,%r20 +L$0020 + extru %r21,15,16,%r19 + addl %r20,%r19,%r20 + zdep %r21,15,16,%r19 + addl %r22,%r19,%r22 + comclr,<<= %r19,%r22,0 + addi,tr 1,%r20,%r19 + copy %r20,%r19 + addl %r22,%r28,%r20 + comclr,<<= %r28,%r20,0 + addi 1,%r19,%r19 + ldw 0(0,%r23),%r28 + addl %r20,%r28,%r20 + comclr,<<= %r28,%r20,0 + addi,tr 1,%r19,%r28 + copy %r19,%r28 + addib,= -1,%r24,L$0003 + stw %r20,0(0,%r23) + ldo 16(%r29),%r29 + ldo 16(%r25),%r25 + ldo 16(%r23),%r23 + bl L$0002,0 + ldo 16(%r26),%r26 +L$0003 + ldw -20(0,%r30),%r2 + bv,n 0(%r2) + .EXIT + .PROCEND + .align 4 + .EXPORT bn_mul_word,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR,RTNVAL=GR +bn_mul_word + .PROC + .CALLINFO FRAME=0,CALLS,SAVE_RP + .ENTRY + stw %r2,-20(0,%r30) + ldi 0,%r28 + extru %r23,31,16,%r2 + stw %r2,-16(0,%r30) + extru %r23,15,16,%r23 + ldil L'65536,%r31 + fldws -16(0,%r30),%fr11R + stw %r23,-16(0,%r30) + ldo 12(%r26),%r29 + ldo 12(%r25),%r23 + fldws -16(0,%r30),%fr11L +L$0026 + ldw 0(0,%r25),%r19 + extru %r19,31,16,%r20 + stw %r20,-16(0,%r30) + extru %r19,15,16,%r19 + fldws -16(0,%r30),%fr22L + stw %r19,-16(0,%r30) + xmpyu %fr22L,%fr11R,%fr8 + fldws -16(0,%r30),%fr22L + fstws %fr8R,-16(0,%r30) + xmpyu %fr11R,%fr22L,%fr10 + ldw -16(0,%r30),%r2 + stw %r20,-16(0,%r30) + xmpyu %fr22L,%fr11L,%fr9 + fldws -16(0,%r30),%fr22L + fstws %fr10R,-16(0,%r30) + copy %r2,%r22 + ldw -16(0,%r30),%r2 + fstws %fr9R,-16(0,%r30) + xmpyu %fr11L,%fr22L,%fr8 + copy %r2,%r19 + ldw -16(0,%r30),%r2 + fstws %fr8R,-16(0,%r30) + copy %r2,%r20 + ldw -16(0,%r30),%r2 + addl %r2,%r19,%r21 + comclr,<<= %r19,%r21,0 + addl %r20,%r31,%r20 +L$0029 + extru %r21,15,16,%r19 + addl %r20,%r19,%r20 + zdep %r21,15,16,%r19 + addl %r22,%r19,%r22 + comclr,<<= %r19,%r22,0 + addi,tr 1,%r20,%r19 + copy %r20,%r19 + addl %r22,%r28,%r20 + comclr,<<= %r28,%r20,0 + addi,tr 1,%r19,%r28 + copy %r19,%r28 + addib,= -1,%r24,L$0027 + stw %r20,0(0,%r26) + ldw -8(0,%r23),%r19 + extru %r19,31,16,%r20 + stw %r20,-16(0,%r30) + extru %r19,15,16,%r19 + fldws -16(0,%r30),%fr22L + stw %r19,-16(0,%r30) + xmpyu %fr22L,%fr11R,%fr8 + fldws -16(0,%r30),%fr22L + fstws %fr8R,-16(0,%r30) + xmpyu %fr11R,%fr22L,%fr10 + ldw -16(0,%r30),%r2 + stw %r20,-16(0,%r30) + xmpyu %fr22L,%fr11L,%fr9 + fldws -16(0,%r30),%fr22L + fstws %fr10R,-16(0,%r30) + copy %r2,%r22 + ldw -16(0,%r30),%r2 + fstws %fr9R,-16(0,%r30) + xmpyu %fr11L,%fr22L,%fr8 + copy %r2,%r19 + ldw -16(0,%r30),%r2 + fstws %fr8R,-16(0,%r30) + copy %r2,%r20 + ldw -16(0,%r30),%r2 + addl %r2,%r19,%r21 + comclr,<<= %r19,%r21,0 + addl %r20,%r31,%r20 +L$0033 + extru %r21,15,16,%r19 + addl %r20,%r19,%r20 + zdep %r21,15,16,%r19 + addl %r22,%r19,%r22 + comclr,<<= %r19,%r22,0 + addi,tr 1,%r20,%r19 + copy %r20,%r19 + addl %r22,%r28,%r20 + comclr,<<= %r28,%r20,0 + addi,tr 1,%r19,%r28 + copy %r19,%r28 + addib,= -1,%r24,L$0027 + stw %r20,-8(0,%r29) + ldw -4(0,%r23),%r19 + extru %r19,31,16,%r20 + stw %r20,-16(0,%r30) + extru %r19,15,16,%r19 + fldws -16(0,%r30),%fr22L + stw %r19,-16(0,%r30) + xmpyu %fr22L,%fr11R,%fr8 + fldws -16(0,%r30),%fr22L + fstws %fr8R,-16(0,%r30) + xmpyu %fr11R,%fr22L,%fr10 + ldw -16(0,%r30),%r2 + stw %r20,-16(0,%r30) + xmpyu %fr22L,%fr11L,%fr9 + fldws -16(0,%r30),%fr22L + fstws %fr10R,-16(0,%r30) + copy %r2,%r22 + ldw -16(0,%r30),%r2 + fstws %fr9R,-16(0,%r30) + xmpyu %fr11L,%fr22L,%fr8 + copy %r2,%r19 + ldw -16(0,%r30),%r2 + fstws %fr8R,-16(0,%r30) + copy %r2,%r20 + ldw -16(0,%r30),%r2 + addl %r2,%r19,%r21 + comclr,<<= %r19,%r21,0 + addl %r20,%r31,%r20 +L$0037 + extru %r21,15,16,%r19 + addl %r20,%r19,%r20 + zdep %r21,15,16,%r19 + addl %r22,%r19,%r22 + comclr,<<= %r19,%r22,0 + addi,tr 1,%r20,%r19 + copy %r20,%r19 + addl %r22,%r28,%r20 + comclr,<<= %r28,%r20,0 + addi,tr 1,%r19,%r28 + copy %r19,%r28 + addib,= -1,%r24,L$0027 + stw %r20,-4(0,%r29) + ldw 0(0,%r23),%r19 + extru %r19,31,16,%r20 + stw %r20,-16(0,%r30) + extru %r19,15,16,%r19 + fldws -16(0,%r30),%fr22L + stw %r19,-16(0,%r30) + xmpyu %fr22L,%fr11R,%fr8 + fldws -16(0,%r30),%fr22L + fstws %fr8R,-16(0,%r30) + xmpyu %fr11R,%fr22L,%fr10 + ldw -16(0,%r30),%r2 + stw %r20,-16(0,%r30) + xmpyu %fr22L,%fr11L,%fr9 + fldws -16(0,%r30),%fr22L + fstws %fr10R,-16(0,%r30) + copy %r2,%r22 + ldw -16(0,%r30),%r2 + fstws %fr9R,-16(0,%r30) + xmpyu %fr11L,%fr22L,%fr8 + copy %r2,%r19 + ldw -16(0,%r30),%r2 + fstws %fr8R,-16(0,%r30) + copy %r2,%r20 + ldw -16(0,%r30),%r2 + addl %r2,%r19,%r21 + comclr,<<= %r19,%r21,0 + addl %r20,%r31,%r20 +L$0041 + extru %r21,15,16,%r19 + addl %r20,%r19,%r20 + zdep %r21,15,16,%r19 + addl %r22,%r19,%r22 + comclr,<<= %r19,%r22,0 + addi,tr 1,%r20,%r19 + copy %r20,%r19 + addl %r22,%r28,%r20 + comclr,<<= %r28,%r20,0 + addi,tr 1,%r19,%r28 + copy %r19,%r28 + addib,= -1,%r24,L$0027 + stw %r20,0(0,%r29) + ldo 16(%r23),%r23 + ldo 16(%r25),%r25 + ldo 16(%r29),%r29 + bl L$0026,0 + ldo 16(%r26),%r26 +L$0027 + ldw -20(0,%r30),%r2 + bv,n 0(%r2) + .EXIT + .PROCEND + .align 4 + .EXPORT bn_sqr_words,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR +bn_sqr_words + .PROC + .CALLINFO FRAME=0,NO_CALLS + .ENTRY + ldo 28(%r26),%r23 + ldo 12(%r25),%r28 +L$0046 + ldw 0(0,%r25),%r21 + extru %r21,31,16,%r22 + stw %r22,-16(0,%r30) + extru %r21,15,16,%r21 + fldws -16(0,%r30),%fr10L + stw %r21,-16(0,%r30) + fldws -16(0,%r30),%fr10R + xmpyu %fr10L,%fr10R,%fr8 + fstws %fr8R,-16(0,%r30) + ldw -16(0,%r30),%r29 + stw %r22,-16(0,%r30) + fldws -16(0,%r30),%fr10R + stw %r21,-16(0,%r30) + copy %r29,%r19 + xmpyu %fr10L,%fr10R,%fr8 + fldws -16(0,%r30),%fr10L + stw %r21,-16(0,%r30) + fldws -16(0,%r30),%fr10R + fstws %fr8R,-16(0,%r30) + extru %r19,16,17,%r20 + zdep %r19,14,15,%r19 + ldw -16(0,%r30),%r29 + xmpyu %fr10L,%fr10R,%fr9 + addl %r29,%r19,%r22 + stw %r22,0(0,%r26) + fstws %fr9R,-16(0,%r30) + ldw -16(0,%r30),%r29 + addl %r29,%r20,%r21 + comclr,<<= %r19,%r22,0 + addi 1,%r21,%r21 + addib,= -1,%r24,L$0057 + stw %r21,-24(0,%r23) + ldw -8(0,%r28),%r21 + extru %r21,31,16,%r22 + stw %r22,-16(0,%r30) + extru %r21,15,16,%r21 + fldws -16(0,%r30),%fr10L + stw %r21,-16(0,%r30) + fldws -16(0,%r30),%fr10R + xmpyu %fr10L,%fr10R,%fr8 + fstws %fr8R,-16(0,%r30) + ldw -16(0,%r30),%r29 + stw %r22,-16(0,%r30) + fldws -16(0,%r30),%fr10R + stw %r21,-16(0,%r30) + copy %r29,%r19 + xmpyu %fr10L,%fr10R,%fr8 + fldws -16(0,%r30),%fr10L + stw %r21,-16(0,%r30) + fldws -16(0,%r30),%fr10R + fstws %fr8R,-16(0,%r30) + extru %r19,16,17,%r20 + zdep %r19,14,15,%r19 + ldw -16(0,%r30),%r29 + xmpyu %fr10L,%fr10R,%fr9 + addl %r29,%r19,%r22 + stw %r22,-20(0,%r23) + fstws %fr9R,-16(0,%r30) + ldw -16(0,%r30),%r29 + addl %r29,%r20,%r21 + comclr,<<= %r19,%r22,0 + addi 1,%r21,%r21 + addib,= -1,%r24,L$0057 + stw %r21,-16(0,%r23) + ldw -4(0,%r28),%r21 + extru %r21,31,16,%r22 + stw %r22,-16(0,%r30) + extru %r21,15,16,%r21 + fldws -16(0,%r30),%fr10L + stw %r21,-16(0,%r30) + fldws -16(0,%r30),%fr10R + xmpyu %fr10L,%fr10R,%fr8 + fstws %fr8R,-16(0,%r30) + ldw -16(0,%r30),%r29 + stw %r22,-16(0,%r30) + fldws -16(0,%r30),%fr10R + stw %r21,-16(0,%r30) + copy %r29,%r19 + xmpyu %fr10L,%fr10R,%fr8 + fldws -16(0,%r30),%fr10L + stw %r21,-16(0,%r30) + fldws -16(0,%r30),%fr10R + fstws %fr8R,-16(0,%r30) + extru %r19,16,17,%r20 + zdep %r19,14,15,%r19 + ldw -16(0,%r30),%r29 + xmpyu %fr10L,%fr10R,%fr9 + addl %r29,%r19,%r22 + stw %r22,-12(0,%r23) + fstws %fr9R,-16(0,%r30) + ldw -16(0,%r30),%r29 + addl %r29,%r20,%r21 + comclr,<<= %r19,%r22,0 + addi 1,%r21,%r21 + addib,= -1,%r24,L$0057 + stw %r21,-8(0,%r23) + ldw 0(0,%r28),%r21 + extru %r21,31,16,%r22 + stw %r22,-16(0,%r30) + extru %r21,15,16,%r21 + fldws -16(0,%r30),%fr10L + stw %r21,-16(0,%r30) + fldws -16(0,%r30),%fr10R + xmpyu %fr10L,%fr10R,%fr8 + fstws %fr8R,-16(0,%r30) + ldw -16(0,%r30),%r29 + stw %r22,-16(0,%r30) + fldws -16(0,%r30),%fr10R + stw %r21,-16(0,%r30) + copy %r29,%r19 + xmpyu %fr10L,%fr10R,%fr8 + fldws -16(0,%r30),%fr10L + stw %r21,-16(0,%r30) + fldws -16(0,%r30),%fr10R + fstws %fr8R,-16(0,%r30) + extru %r19,16,17,%r20 + zdep %r19,14,15,%r19 + ldw -16(0,%r30),%r29 + xmpyu %fr10L,%fr10R,%fr9 + addl %r29,%r19,%r22 + stw %r22,-4(0,%r23) + fstws %fr9R,-16(0,%r30) + ldw -16(0,%r30),%r29 + addl %r29,%r20,%r21 + comclr,<<= %r19,%r22,0 + addi 1,%r21,%r21 + addib,= -1,%r24,L$0057 + stw %r21,0(0,%r23) + ldo 16(%r28),%r28 + ldo 16(%r25),%r25 + ldo 32(%r23),%r23 + bl L$0046,0 + ldo 32(%r26),%r26 +L$0057 + bv,n 0(%r2) + .EXIT + .PROCEND + .IMPORT BN_num_bits_word,CODE + .IMPORT fprintf,CODE + .IMPORT __iob,DATA + .SPACE $TEXT$ + .SUBSPA $LIT$ + + .align 4 +L$C0000 + .STRING "Division would overflow\x0a\x00" + .IMPORT abort,CODE + .SPACE $TEXT$ + .SUBSPA $CODE$ + + .align 4 + .EXPORT bn_div64,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,RTNVAL=GR +bn_div64 + .PROC + .CALLINFO FRAME=128,CALLS,SAVE_RP,ENTRY_GR=8 + .ENTRY + stw %r2,-20(0,%r30) + stwm %r8,128(0,%r30) + stw %r7,-124(0,%r30) + stw %r4,-112(0,%r30) + stw %r3,-108(0,%r30) + copy %r26,%r3 + copy %r25,%r4 + stw %r6,-120(0,%r30) + ldi 0,%r7 + stw %r5,-116(0,%r30) + movb,<> %r24,%r5,L$0059 + ldi 2,%r6 + bl L$0076,0 + ldi -1,%r28 +L$0059 + .CALL ARGW0=GR + bl BN_num_bits_word,%r2 + copy %r5,%r26 + ldi 32,%r19 + comb,= %r19,%r28,L$0060 + subi 31,%r28,%r19 + mtsar %r19 + zvdepi 1,32,%r19 + comb,>>= %r19,%r3,L$0060 + addil LR'__iob-$global$+32,%r27 + ldo RR'__iob-$global$+32(%r1),%r26 + ldil LR'L$C0000,%r25 + .CALL ARGW0=GR,ARGW1=GR + bl fprintf,%r2 + ldo RR'L$C0000(%r25),%r25 + .CALL + bl abort,%r2 + nop +L$0060 + comb,>> %r5,%r3,L$0061 + subi 32,%r28,%r28 + sub %r3,%r5,%r3 +L$0061 + comib,= 0,%r28,L$0062 + subi 31,%r28,%r19 + mtsar %r19 + zvdep %r5,32,%r5 + zvdep %r3,32,%r21 + subi 32,%r28,%r20 + mtsar %r20 + vshd 0,%r4,%r20 + or %r21,%r20,%r3 + mtsar %r19 + zvdep %r4,32,%r4 +L$0062 + extru %r5,15,16,%r23 + extru %r5,31,16,%r28 +L$0063 + extru %r3,15,16,%r19 + comb,<> %r23,%r19,L$0066 + copy %r3,%r26 + bl L$0067,0 + zdepi -1,31,16,%r29 +L$0066 + .IMPORT $$divU,MILLICODE + bl $$divU,%r31 + copy %r23,%r25 +L$0067 + stw %r29,-16(0,%r30) + fldws -16(0,%r30),%fr10L + stw %r28,-16(0,%r30) + fldws -16(0,%r30),%fr10R + stw %r23,-16(0,%r30) + xmpyu %fr10L,%fr10R,%fr8 + fldws -16(0,%r30),%fr10R + fstws %fr8R,-16(0,%r30) + xmpyu %fr10L,%fr10R,%fr9 + ldw -16(0,%r30),%r8 + fstws %fr9R,-16(0,%r30) + copy %r8,%r22 + ldw -16(0,%r30),%r8 + extru %r4,15,16,%r24 + copy %r8,%r21 +L$0068 + sub %r3,%r21,%r20 + copy %r20,%r19 + depi 0,31,16,%r19 + comib,<> 0,%r19,L$0069 + zdep %r20,15,16,%r19 + addl %r19,%r24,%r19 + comb,>>= %r19,%r22,L$0069 + sub %r22,%r28,%r22 + sub %r21,%r23,%r21 + bl L$0068,0 + ldo -1(%r29),%r29 +L$0069 + stw %r29,-16(0,%r30) + fldws -16(0,%r30),%fr10L + stw %r28,-16(0,%r30) + fldws -16(0,%r30),%fr10R + xmpyu %fr10L,%fr10R,%fr8 + fstws %fr8R,-16(0,%r30) + ldw -16(0,%r30),%r8 + stw %r23,-16(0,%r30) + fldws -16(0,%r30),%fr10R + copy %r8,%r19 + xmpyu %fr10L,%fr10R,%fr8 + fstws %fr8R,-16(0,%r30) + extru %r19,15,16,%r20 + ldw -16(0,%r30),%r8 + zdep %r19,15,16,%r19 + addl %r8,%r20,%r20 + comclr,<<= %r19,%r4,0 + addi 1,%r20,%r20 + comb,<<= %r20,%r3,L$0074 + sub %r4,%r19,%r4 + addl %r3,%r5,%r3 + ldo -1(%r29),%r29 +L$0074 + addib,= -1,%r6,L$0064 + sub %r3,%r20,%r3 + zdep %r29,15,16,%r7 + shd %r3,%r4,16,%r3 + bl L$0063,0 + zdep %r4,15,16,%r4 +L$0064 + or %r7,%r29,%r28 +L$0076 + ldw -148(0,%r30),%r2 + ldw -124(0,%r30),%r7 + ldw -120(0,%r30),%r6 + ldw -116(0,%r30),%r5 + ldw -112(0,%r30),%r4 + ldw -108(0,%r30),%r3 + bv 0(%r2) + ldwm -128(0,%r30),%r8 + .EXIT + .PROCEND diff --git a/crypto/bn/asm/pa-risc2.s b/crypto/bn/asm/pa-risc2.s new file mode 100644 index 0000000000..5e07b7d2e8 --- /dev/null +++ b/crypto/bn/asm/pa-risc2.s @@ -0,0 +1,416 @@ + .SPACE $PRIVATE$ + .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31 + .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82 + .SPACE $TEXT$ + .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44 + .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY + .IMPORT $global$,DATA + .IMPORT $$dyncall,MILLICODE +; gcc_compiled.: + .SPACE $TEXT$ + .SUBSPA $CODE$ + + .align 4 + .EXPORT bn_mul_add_word,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR,RTNVAL=GR +bn_mul_add_word + .PROC + .CALLINFO FRAME=64,CALLS,SAVE_RP,ENTRY_GR=4 + .ENTRY + stw %r2,-20(0,%r30) + stwm %r4,64(0,%r30) + copy %r24,%r31 + stw %r3,-60(0,%r30) + ldi 0,%r20 + ldo 12(%r26),%r2 + stw %r23,-16(0,%r30) + copy %r25,%r3 + ldo 12(%r3),%r1 + fldws -16(0,%r30),%fr8L +L$0010 + copy %r20,%r25 + ldi 0,%r24 + fldws 0(0,%r3),%fr9L + ldw 0(0,%r26),%r19 + xmpyu %fr8L,%fr9L,%fr9 + fstds %fr9,-16(0,%r30) + copy %r19,%r23 + ldw -16(0,%r30),%r28 + ldw -12(0,%r30),%r29 + ldi 0,%r22 + add %r23,%r29,%r29 + addc %r22,%r28,%r28 + add %r25,%r29,%r29 + addc %r24,%r28,%r28 + copy %r28,%r21 + ldi 0,%r20 + copy %r21,%r20 + addib,= -1,%r31,L$0011 + stw %r29,0(0,%r26) + copy %r20,%r25 + ldi 0,%r24 + fldws -8(0,%r1),%fr9L + ldw -8(0,%r2),%r19 + xmpyu %fr8L,%fr9L,%fr9 + fstds %fr9,-16(0,%r30) + copy %r19,%r23 + ldw -16(0,%r30),%r28 + ldw -12(0,%r30),%r29 + ldi 0,%r22 + add %r23,%r29,%r29 + addc %r22,%r28,%r28 + add %r25,%r29,%r29 + addc %r24,%r28,%r28 + copy %r28,%r21 + ldi 0,%r20 + copy %r21,%r20 + addib,= -1,%r31,L$0011 + stw %r29,-8(0,%r2) + copy %r20,%r25 + ldi 0,%r24 + fldws -4(0,%r1),%fr9L + ldw -4(0,%r2),%r19 + xmpyu %fr8L,%fr9L,%fr9 + fstds %fr9,-16(0,%r30) + copy %r19,%r23 + ldw -16(0,%r30),%r28 + ldw -12(0,%r30),%r29 + ldi 0,%r22 + add %r23,%r29,%r29 + addc %r22,%r28,%r28 + add %r25,%r29,%r29 + addc %r24,%r28,%r28 + copy %r28,%r21 + ldi 0,%r20 + copy %r21,%r20 + addib,= -1,%r31,L$0011 + stw %r29,-4(0,%r2) + copy %r20,%r25 + ldi 0,%r24 + fldws 0(0,%r1),%fr9L + ldw 0(0,%r2),%r19 + xmpyu %fr8L,%fr9L,%fr9 + fstds %fr9,-16(0,%r30) + copy %r19,%r23 + ldw -16(0,%r30),%r28 + ldw -12(0,%r30),%r29 + ldi 0,%r22 + add %r23,%r29,%r29 + addc %r22,%r28,%r28 + add %r25,%r29,%r29 + addc %r24,%r28,%r28 + copy %r28,%r21 + ldi 0,%r20 + copy %r21,%r20 + addib,= -1,%r31,L$0011 + stw %r29,0(0,%r2) + ldo 16(%r1),%r1 + ldo 16(%r3),%r3 + ldo 16(%r2),%r2 + bl L$0010,0 + ldo 16(%r26),%r26 +L$0011 + copy %r20,%r28 + ldw -84(0,%r30),%r2 + ldw -60(0,%r30),%r3 + bv 0(%r2) + ldwm -64(0,%r30),%r4 + .EXIT + .PROCEND + .align 4 + .EXPORT bn_mul_word,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR,RTNVAL=GR +bn_mul_word + .PROC + .CALLINFO FRAME=64,CALLS,SAVE_RP,ENTRY_GR=3 + .ENTRY + stw %r2,-20(0,%r30) + copy %r25,%r2 + stwm %r4,64(0,%r30) + copy %r24,%r19 + ldi 0,%r28 + stw %r23,-16(0,%r30) + ldo 12(%r26),%r31 + ldo 12(%r2),%r29 + fldws -16(0,%r30),%fr8L +L$0026 + fldws 0(0,%r2),%fr9L + xmpyu %fr8L,%fr9L,%fr9 + fstds %fr9,-16(0,%r30) + copy %r28,%r21 + ldi 0,%r20 + ldw -16(0,%r30),%r24 + ldw -12(0,%r30),%r25 + add %r21,%r25,%r25 + addc %r20,%r24,%r24 + copy %r24,%r23 + ldi 0,%r22 + copy %r23,%r28 + addib,= -1,%r19,L$0027 + stw %r25,0(0,%r26) + fldws -8(0,%r29),%fr9L + xmpyu %fr8L,%fr9L,%fr9 + fstds %fr9,-16(0,%r30) + copy %r28,%r21 + ldi 0,%r20 + ldw -16(0,%r30),%r24 + ldw -12(0,%r30),%r25 + add %r21,%r25,%r25 + addc %r20,%r24,%r24 + copy %r24,%r23 + ldi 0,%r22 + copy %r23,%r28 + addib,= -1,%r19,L$0027 + stw %r25,-8(0,%r31) + fldws -4(0,%r29),%fr9L + xmpyu %fr8L,%fr9L,%fr9 + fstds %fr9,-16(0,%r30) + copy %r28,%r21 + ldi 0,%r20 + ldw -16(0,%r30),%r24 + ldw -12(0,%r30),%r25 + add %r21,%r25,%r25 + addc %r20,%r24,%r24 + copy %r24,%r23 + ldi 0,%r22 + copy %r23,%r28 + addib,= -1,%r19,L$0027 + stw %r25,-4(0,%r31) + fldws 0(0,%r29),%fr9L + xmpyu %fr8L,%fr9L,%fr9 + fstds %fr9,-16(0,%r30) + copy %r28,%r21 + ldi 0,%r20 + ldw -16(0,%r30),%r24 + ldw -12(0,%r30),%r25 + add %r21,%r25,%r25 + addc %r20,%r24,%r24 + copy %r24,%r23 + ldi 0,%r22 + copy %r23,%r28 + addib,= -1,%r19,L$0027 + stw %r25,0(0,%r31) + ldo 16(%r29),%r29 + ldo 16(%r2),%r2 + ldo 16(%r31),%r31 + bl L$0026,0 + ldo 16(%r26),%r26 +L$0027 + ldw -84(0,%r30),%r2 + bv 0(%r2) + ldwm -64(0,%r30),%r4 + .EXIT + .PROCEND + .align 4 + .EXPORT bn_sqr_words,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR +bn_sqr_words + .PROC + .CALLINFO FRAME=0,NO_CALLS + .ENTRY + ldo 28(%r26),%r19 + ldo 12(%r25),%r28 +L$0042 + fldws 0(0,%r25),%fr8L + fldws 0(0,%r25),%fr8R + xmpyu %fr8L,%fr8R,%fr8 + fstds %fr8,-16(0,%r30) + ldw -16(0,%r30),%r22 + ldw -12(0,%r30),%r23 + stw %r23,0(0,%r26) + copy %r22,%r21 + ldi 0,%r20 + addib,= -1,%r24,L$0049 + stw %r21,-24(0,%r19) + fldws -8(0,%r28),%fr8L + fldws -8(0,%r28),%fr8R + xmpyu %fr8L,%fr8R,%fr8 + fstds %fr8,-16(0,%r30) + ldw -16(0,%r30),%r22 + ldw -12(0,%r30),%r23 + stw %r23,-20(0,%r19) + copy %r22,%r21 + ldi 0,%r20 + addib,= -1,%r24,L$0049 + stw %r21,-16(0,%r19) + fldws -4(0,%r28),%fr8L + fldws -4(0,%r28),%fr8R + xmpyu %fr8L,%fr8R,%fr8 + fstds %fr8,-16(0,%r30) + ldw -16(0,%r30),%r22 + ldw -12(0,%r30),%r23 + stw %r23,-12(0,%r19) + copy %r22,%r21 + ldi 0,%r20 + addib,= -1,%r24,L$0049 + stw %r21,-8(0,%r19) + fldws 0(0,%r28),%fr8L + fldws 0(0,%r28),%fr8R + xmpyu %fr8L,%fr8R,%fr8 + fstds %fr8,-16(0,%r30) + ldw -16(0,%r30),%r22 + ldw -12(0,%r30),%r23 + stw %r23,-4(0,%r19) + copy %r22,%r21 + ldi 0,%r20 + addib,= -1,%r24,L$0049 + stw %r21,0(0,%r19) + ldo 16(%r28),%r28 + ldo 16(%r25),%r25 + ldo 32(%r19),%r19 + bl L$0042,0 + ldo 32(%r26),%r26 +L$0049 + bv,n 0(%r2) + .EXIT + .PROCEND + .IMPORT BN_num_bits_word,CODE + .IMPORT fprintf,CODE + .IMPORT __iob,DATA + .SPACE $TEXT$ + .SUBSPA $LIT$ + + .align 4 +L$C0000 + .STRING "Division would overflow (%d)\x0a\x00" + .IMPORT abort,CODE + .SPACE $TEXT$ + .SUBSPA $CODE$ + + .align 4 + .EXPORT bn_div64,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,RTNVAL=GR +bn_div64 + .PROC + .CALLINFO FRAME=128,CALLS,SAVE_RP,ENTRY_GR=8 + .ENTRY + stw %r2,-20(0,%r30) + stwm %r8,128(0,%r30) + stw %r7,-124(0,%r30) + stw %r4,-112(0,%r30) + stw %r3,-108(0,%r30) + copy %r26,%r3 + copy %r25,%r4 + stw %r6,-120(0,%r30) + ldi 0,%r7 + stw %r5,-116(0,%r30) + movb,<> %r24,%r5,L$0051 + ldi 2,%r6 + bl L$0068,0 + ldi -1,%r28 +L$0051 + .CALL ARGW0=GR + bl BN_num_bits_word,%r2 + copy %r5,%r26 + copy %r28,%r24 + ldi 32,%r19 + comb,= %r19,%r24,L$0052 + subi 31,%r24,%r19 + mtsar %r19 + zvdepi 1,32,%r19 + comb,>>= %r19,%r3,L$0052 + addil LR'__iob-$global$+32,%r27 + ldo RR'__iob-$global$+32(%r1),%r26 + ldil LR'L$C0000,%r25 + .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR + bl fprintf,%r2 + ldo RR'L$C0000(%r25),%r25 + .CALL + bl abort,%r2 + nop +L$0052 + comb,>> %r5,%r3,L$0053 + subi 32,%r24,%r24 + sub %r3,%r5,%r3 +L$0053 + comib,= 0,%r24,L$0054 + subi 31,%r24,%r19 + mtsar %r19 + zvdep %r5,32,%r5 + zvdep %r3,32,%r21 + subi 32,%r24,%r20 + mtsar %r20 + vshd 0,%r4,%r20 + or %r21,%r20,%r3 + mtsar %r19 + zvdep %r4,32,%r4 +L$0054 + extru %r5,15,16,%r23 + extru %r5,31,16,%r28 +L$0055 + extru %r3,15,16,%r19 + comb,<> %r23,%r19,L$0058 + copy %r3,%r26 + bl L$0059,0 + zdepi -1,31,16,%r29 +L$0058 + .IMPORT $$divU,MILLICODE + bl $$divU,%r31 + copy %r23,%r25 +L$0059 + stw %r29,-16(0,%r30) + fldws -16(0,%r30),%fr10L + stw %r28,-16(0,%r30) + fldws -16(0,%r30),%fr10R + stw %r23,-16(0,%r30) + xmpyu %fr10L,%fr10R,%fr8 + fldws -16(0,%r30),%fr10R + fstws %fr8R,-16(0,%r30) + xmpyu %fr10L,%fr10R,%fr9 + ldw -16(0,%r30),%r8 + fstws %fr9R,-16(0,%r30) + copy %r8,%r22 + ldw -16(0,%r30),%r8 + extru %r4,15,16,%r24 + copy %r8,%r21 +L$0060 + sub %r3,%r21,%r20 + copy %r20,%r19 + depi 0,31,16,%r19 + comib,<> 0,%r19,L$0061 + zdep %r20,15,16,%r19 + addl %r19,%r24,%r19 + comb,>>= %r19,%r22,L$0061 + sub %r22,%r28,%r22 + sub %r21,%r23,%r21 + bl L$0060,0 + ldo -1(%r29),%r29 +L$0061 + stw %r29,-16(0,%r30) + fldws -16(0,%r30),%fr10L + stw %r28,-16(0,%r30) + fldws -16(0,%r30),%fr10R + xmpyu %fr10L,%fr10R,%fr8 + fstws %fr8R,-16(0,%r30) + ldw -16(0,%r30),%r8 + stw %r23,-16(0,%r30) + fldws -16(0,%r30),%fr10R + copy %r8,%r19 + xmpyu %fr10L,%fr10R,%fr8 + fstws %fr8R,-16(0,%r30) + extru %r19,15,16,%r20 + ldw -16(0,%r30),%r8 + zdep %r19,15,16,%r19 + addl %r8,%r20,%r20 + comclr,<<= %r19,%r4,0 + addi 1,%r20,%r20 + comb,<<= %r20,%r3,L$0066 + sub %r4,%r19,%r4 + addl %r3,%r5,%r3 + ldo -1(%r29),%r29 +L$0066 + addib,= -1,%r6,L$0056 + sub %r3,%r20,%r3 + zdep %r29,15,16,%r7 + shd %r3,%r4,16,%r3 + bl L$0055,0 + zdep %r4,15,16,%r4 +L$0056 + or %r7,%r29,%r28 +L$0068 + ldw -148(0,%r30),%r2 + ldw -124(0,%r30),%r7 + ldw -120(0,%r30),%r6 + ldw -116(0,%r30),%r5 + ldw -112(0,%r30),%r4 + ldw -108(0,%r30),%r3 + bv 0(%r2) + ldwm -128(0,%r30),%r8 + .EXIT + .PROCEND diff --git a/crypto/bn/asm/r3000.s b/crypto/bn/asm/r3000.s new file mode 100644 index 0000000000..5be2a0d0e6 --- /dev/null +++ b/crypto/bn/asm/r3000.s @@ -0,0 +1,646 @@ + .file 1 "../bn_mulw.c" + .set nobopt + .option pic2 + + # GNU C 2.6.3 [AL 1.1, MM 40] SGI running IRIX 5.0 compiled by GNU C + + # Cc1 defaults: + # -mabicalls + + # Cc1 arguments (-G value = 0, Cpu = 3000, ISA = 1): + # -quiet -dumpbase -O2 -o + +gcc2_compiled.: +__gnu_compiled_c: + .rdata + + .byte 0x24,0x52,0x65,0x76,0x69,0x73,0x69,0x6f + .byte 0x6e,0x3a,0x20,0x31,0x2e,0x34,0x39,0x20 + .byte 0x24,0x0 + + .byte 0x24,0x52,0x65,0x76,0x69,0x73,0x69,0x6f + .byte 0x6e,0x3a,0x20,0x31,0x2e,0x33,0x34,0x20 + .byte 0x24,0x0 + + .byte 0x24,0x52,0x65,0x76,0x69,0x73,0x69,0x6f + .byte 0x6e,0x3a,0x20,0x31,0x2e,0x35,0x20,0x24 + .byte 0x0 + + .byte 0x24,0x52,0x65,0x76,0x69,0x73,0x69,0x6f + .byte 0x6e,0x3a,0x20,0x31,0x2e,0x38,0x20,0x24 + .byte 0x0 + + .byte 0x24,0x52,0x65,0x76,0x69,0x73,0x69,0x6f + .byte 0x6e,0x3a,0x20,0x31,0x2e,0x32,0x33,0x20 + .byte 0x24,0x0 + + .byte 0x24,0x52,0x65,0x76,0x69,0x73,0x69,0x6f + .byte 0x6e,0x3a,0x20,0x31,0x2e,0x37,0x38,0x20 + .byte 0x24,0x0 + + .byte 0x24,0x52,0x65,0x76,0x69,0x73,0x69,0x6f + .byte 0x6e,0x3a,0x20,0x33,0x2e,0x37,0x30,0x20 + .byte 0x24,0x0 + + .byte 0x24,0x52,0x65,0x76,0x69,0x73,0x69,0x6f + .byte 0x6e,0x3a,0x20,0x31,0x2e,0x32,0x20,0x24 + .byte 0x0 + + .byte 0x24,0x52,0x65,0x76,0x69,0x73,0x69,0x6f + .byte 0x6e,0x3a,0x20,0x31,0x2e,0x34,0x20,0x24 + .byte 0x0 + + .byte 0x24,0x52,0x65,0x76,0x69,0x73,0x69,0x6f + .byte 0x6e,0x3a,0x20,0x31,0x2e,0x38,0x20,0x24 + .byte 0x0 + .text + .align 2 + .globl bn_mul_add_word + .ent bn_mul_add_word +bn_mul_add_word: + .frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, extra= 0 + .mask 0x00000000,0 + .fmask 0x00000000,0 + .set noreorder + .cpload $25 + .set reorder + move $12,$4 + move $14,$5 + move $9,$6 + move $13,$7 + move $8,$0 + addu $10,$12,12 + addu $11,$14,12 +$L2: + lw $6,0($14) + #nop + multu $13,$6 + mfhi $6 + mflo $7 + #nop + move $5,$8 + move $4,$0 + lw $3,0($12) + addu $9,$9,-1 + move $2,$0 + addu $7,$7,$3 + sltu $8,$7,$3 + addu $6,$6,$2 + addu $6,$6,$8 + addu $7,$7,$5 + sltu $2,$7,$5 + addu $6,$6,$4 + addu $6,$6,$2 + srl $3,$6,0 + move $2,$0 + move $8,$3 + .set noreorder + .set nomacro + beq $9,$0,$L3 + sw $7,0($12) + .set macro + .set reorder + + lw $6,-8($11) + #nop + multu $13,$6 + mfhi $6 + mflo $7 + #nop + move $5,$8 + move $4,$0 + lw $3,-8($10) + addu $9,$9,-1 + move $2,$0 + addu $7,$7,$3 + sltu $8,$7,$3 + addu $6,$6,$2 + addu $6,$6,$8 + addu $7,$7,$5 + sltu $2,$7,$5 + addu $6,$6,$4 + addu $6,$6,$2 + srl $3,$6,0 + move $2,$0 + move $8,$3 + .set noreorder + .set nomacro + beq $9,$0,$L3 + sw $7,-8($10) + .set macro + .set reorder + + lw $6,-4($11) + #nop + multu $13,$6 + mfhi $6 + mflo $7 + #nop + move $5,$8 + move $4,$0 + lw $3,-4($10) + addu $9,$9,-1 + move $2,$0 + addu $7,$7,$3 + sltu $8,$7,$3 + addu $6,$6,$2 + addu $6,$6,$8 + addu $7,$7,$5 + sltu $2,$7,$5 + addu $6,$6,$4 + addu $6,$6,$2 + srl $3,$6,0 + move $2,$0 + move $8,$3 + .set noreorder + .set nomacro + beq $9,$0,$L3 + sw $7,-4($10) + .set macro + .set reorder + + lw $6,0($11) + #nop + multu $13,$6 + mfhi $6 + mflo $7 + #nop + move $5,$8 + move $4,$0 + lw $3,0($10) + addu $9,$9,-1 + move $2,$0 + addu $7,$7,$3 + sltu $8,$7,$3 + addu $6,$6,$2 + addu $6,$6,$8 + addu $7,$7,$5 + sltu $2,$7,$5 + addu $6,$6,$4 + addu $6,$6,$2 + srl $3,$6,0 + move $2,$0 + move $8,$3 + .set noreorder + .set nomacro + beq $9,$0,$L3 + sw $7,0($10) + .set macro + .set reorder + + addu $11,$11,16 + addu $14,$14,16 + addu $10,$10,16 + .set noreorder + .set nomacro + j $L2 + addu $12,$12,16 + .set macro + .set reorder + +$L3: + .set noreorder + .set nomacro + j $31 + move $2,$8 + .set macro + .set reorder + + .end bn_mul_add_word + .align 2 + .globl bn_mul_word + .ent bn_mul_word +bn_mul_word: + .frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, extra= 0 + .mask 0x00000000,0 + .fmask 0x00000000,0 + .set noreorder + .cpload $25 + .set reorder + move $11,$4 + move $12,$5 + move $8,$6 + move $6,$0 + addu $10,$11,12 + addu $9,$12,12 +$L10: + lw $4,0($12) + #nop + multu $7,$4 + mfhi $4 + mflo $5 + #nop + move $3,$6 + move $2,$0 + addu $8,$8,-1 + addu $5,$5,$3 + sltu $6,$5,$3 + addu $4,$4,$2 + addu $4,$4,$6 + srl $3,$4,0 + move $2,$0 + move $6,$3 + .set noreorder + .set nomacro + beq $8,$0,$L11 + sw $5,0($11) + .set macro + .set reorder + + lw $4,-8($9) + #nop + multu $7,$4 + mfhi $4 + mflo $5 + #nop + move $3,$6 + move $2,$0 + addu $8,$8,-1 + addu $5,$5,$3 + sltu $6,$5,$3 + addu $4,$4,$2 + addu $4,$4,$6 + srl $3,$4,0 + move $2,$0 + move $6,$3 + .set noreorder + .set nomacro + beq $8,$0,$L11 + sw $5,-8($10) + .set macro + .set reorder + + lw $4,-4($9) + #nop + multu $7,$4 + mfhi $4 + mflo $5 + #nop + move $3,$6 + move $2,$0 + addu $8,$8,-1 + addu $5,$5,$3 + sltu $6,$5,$3 + addu $4,$4,$2 + addu $4,$4,$6 + srl $3,$4,0 + move $2,$0 + move $6,$3 + .set noreorder + .set nomacro + beq $8,$0,$L11 + sw $5,-4($10) + .set macro + .set reorder + + lw $4,0($9) + #nop + multu $7,$4 + mfhi $4 + mflo $5 + #nop + move $3,$6 + move $2,$0 + addu $8,$8,-1 + addu $5,$5,$3 + sltu $6,$5,$3 + addu $4,$4,$2 + addu $4,$4,$6 + srl $3,$4,0 + move $2,$0 + move $6,$3 + .set noreorder + .set nomacro + beq $8,$0,$L11 + sw $5,0($10) + .set macro + .set reorder + + addu $9,$9,16 + addu $12,$12,16 + addu $10,$10,16 + .set noreorder + .set nomacro + j $L10 + addu $11,$11,16 + .set macro + .set reorder + +$L11: + .set noreorder + .set nomacro + j $31 + move $2,$6 + .set macro + .set reorder + + .end bn_mul_word + .align 2 + .globl bn_sqr_words + .ent bn_sqr_words +bn_sqr_words: + .frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, extra= 0 + .mask 0x00000000,0 + .fmask 0x00000000,0 + .set noreorder + .cpload $25 + .set reorder + move $9,$4 + addu $7,$9,28 + addu $8,$5,12 +$L18: + lw $2,0($5) + #nop + multu $2,$2 + mfhi $2 + mflo $3 + #nop + addu $6,$6,-1 + sw $3,0($9) + srl $3,$2,0 + move $2,$0 + .set noreorder + .set nomacro + beq $6,$0,$L19 + sw $3,-24($7) + .set macro + .set reorder + + lw $2,-8($8) + #nop + multu $2,$2 + mfhi $2 + mflo $3 + #nop + addu $6,$6,-1 + sw $3,-20($7) + srl $3,$2,0 + move $2,$0 + .set noreorder + .set nomacro + beq $6,$0,$L19 + sw $3,-16($7) + .set macro + .set reorder + + lw $2,-4($8) + #nop + multu $2,$2 + mfhi $2 + mflo $3 + #nop + addu $6,$6,-1 + sw $3,-12($7) + srl $3,$2,0 + move $2,$0 + .set noreorder + .set nomacro + beq $6,$0,$L19 + sw $3,-8($7) + .set macro + .set reorder + + lw $2,0($8) + #nop + multu $2,$2 + mfhi $2 + mflo $3 + #nop + addu $6,$6,-1 + sw $3,-4($7) + srl $3,$2,0 + move $2,$0 + .set noreorder + .set nomacro + beq $6,$0,$L19 + sw $3,0($7) + .set macro + .set reorder + + addu $8,$8,16 + addu $5,$5,16 + addu $7,$7,32 + .set noreorder + .set nomacro + j $L18 + addu $9,$9,32 + .set macro + .set reorder + +$L19: + j $31 + .end bn_sqr_words + .rdata + .align 2 +$LC0: + + .byte 0x44,0x69,0x76,0x69,0x73,0x69,0x6f,0x6e + .byte 0x20,0x77,0x6f,0x75,0x6c,0x64,0x20,0x6f + .byte 0x76,0x65,0x72,0x66,0x6c,0x6f,0x77,0xa + .byte 0x0 + .text + .align 2 + .globl bn_div64 + .ent bn_div64 +bn_div64: + .frame $sp,56,$31 # vars= 0, regs= 7/0, args= 16, extra= 8 + .mask 0x901f0000,-8 + .fmask 0x00000000,0 + .set noreorder + .cpload $25 + .set reorder + subu $sp,$sp,56 + .cprestore 16 + sw $16,24($sp) + move $16,$4 + sw $17,28($sp) + move $17,$5 + sw $18,32($sp) + move $18,$6 + sw $20,40($sp) + move $20,$0 + sw $19,36($sp) + li $19,0x00000002 # 2 + sw $31,48($sp) + .set noreorder + .set nomacro + bne $18,$0,$L26 + sw $28,44($sp) + .set macro + .set reorder + + .set noreorder + .set nomacro + j $L43 + li $2,-1 # 0xffffffff + .set macro + .set reorder + +$L26: + move $4,$18 + jal BN_num_bits_word + move $4,$2 + li $2,0x00000020 # 32 + .set noreorder + .set nomacro + beq $4,$2,$L27 + li $2,0x00000001 # 1 + .set macro + .set reorder + + sll $2,$2,$4 + sltu $2,$2,$16 + .set noreorder + .set nomacro + beq $2,$0,$L44 + li $5,0x00000020 # 32 + .set macro + .set reorder + + la $4,__iob+32 + la $5,$LC0 + jal fprintf + jal abort +$L27: + li $5,0x00000020 # 32 +$L44: + sltu $2,$16,$18 + .set noreorder + .set nomacro + bne $2,$0,$L28 + subu $4,$5,$4 + .set macro + .set reorder + + subu $16,$16,$18 +$L28: + .set noreorder + .set nomacro + beq $4,$0,$L29 + li $10,-65536 # 0xffff0000 + .set macro + .set reorder + + sll $18,$18,$4 + sll $3,$16,$4 + subu $2,$5,$4 + srl $2,$17,$2 + or $16,$3,$2 + sll $17,$17,$4 +$L29: + srl $7,$18,16 + andi $9,$18,0xffff +$L30: + srl $2,$16,16 + .set noreorder + .set nomacro + beq $2,$7,$L34 + li $6,0x0000ffff # 65535 + .set macro + .set reorder + + divu $6,$16,$7 +$L34: + mult $6,$9 + mflo $5 + #nop + #nop + mult $6,$7 + and $2,$17,$10 + srl $8,$2,16 + mflo $4 +$L35: + subu $3,$16,$4 + and $2,$3,$10 + .set noreorder + .set nomacro + bne $2,$0,$L36 + sll $2,$3,16 + .set macro + .set reorder + + addu $2,$2,$8 + sltu $2,$2,$5 + .set noreorder + .set nomacro + beq $2,$0,$L36 + subu $5,$5,$9 + .set macro + .set reorder + + subu $4,$4,$7 + .set noreorder + .set nomacro + j $L35 + addu $6,$6,-1 + .set macro + .set reorder + +$L36: + mult $6,$7 + mflo $5 + #nop + #nop + mult $6,$9 + mflo $4 + #nop + #nop + srl $3,$4,16 + sll $2,$4,16 + and $4,$2,$10 + sltu $2,$17,$4 + .set noreorder + .set nomacro + beq $2,$0,$L40 + addu $5,$5,$3 + .set macro + .set reorder + + addu $5,$5,1 +$L40: + sltu $2,$16,$5 + .set noreorder + .set nomacro + beq $2,$0,$L41 + subu $17,$17,$4 + .set macro + .set reorder + + addu $16,$16,$18 + addu $6,$6,-1 +$L41: + addu $19,$19,-1 + .set noreorder + .set nomacro + beq $19,$0,$L31 + subu $16,$16,$5 + .set macro + .set reorder + + sll $20,$6,16 + sll $3,$16,16 + srl $2,$17,16 + or $16,$3,$2 + .set noreorder + .set nomacro + j $L30 + sll $17,$17,16 + .set macro + .set reorder + +$L31: + or $2,$20,$6 +$L43: + lw $31,48($sp) + lw $20,40($sp) + lw $19,36($sp) + lw $18,32($sp) + lw $17,28($sp) + lw $16,24($sp) + addu $sp,$sp,56 + j $31 + .end bn_div64 + + .globl abort .text + .globl fprintf .text + .globl BN_num_bits_word .text diff --git a/crypto/bn/asm/sparc.s b/crypto/bn/asm/sparc.s new file mode 100644 index 0000000000..37c5fb194e --- /dev/null +++ b/crypto/bn/asm/sparc.s @@ -0,0 +1,359 @@ + .file "bn_mulw.c" +gcc2_compiled.: +.section ".text" + .align 4 + .global bn_mul_add_word + .type bn_mul_add_word,#function + .proc 016 +bn_mul_add_word: + !#PROLOGUE# 0 + save %sp,-112,%sp + !#PROLOGUE# 1 + mov %i0,%o0 + mov %i1,%o2 + mov %i2,%g1 + mov %i3,%o1 + mov 0,%i4 + add %o0,12,%g4 + add %o2,12,%o7 +.LL2: + mov %i4,%i3 + mov 0,%i2 + ld [%o0],%g2 + mov %g2,%i1 + ld [%o2],%g2 + mov 0,%i0 + umul %o1,%g2,%g3 + rd %y,%g2 + addcc %g3,%i1,%g3 + addx %g2,%i0,%g2 + addcc %g3,%i3,%g3 + addx %g2,%i2,%g2 + st %g3,[%o0] + mov %g2,%i5 + mov 0,%i4 + addcc %g1,-1,%g1 + be .LL3 + mov %i5,%i4 + mov %i4,%i3 + mov 0,%i2 + ld [%g4-8],%g2 + mov %g2,%i1 + ld [%o7-8],%g2 + mov 0,%i0 + umul %o1,%g2,%g3 + rd %y,%g2 + addcc %g3,%i1,%g3 + addx %g2,%i0,%g2 + addcc %g3,%i3,%g3 + addx %g2,%i2,%g2 + st %g3,[%g4-8] + mov %g2,%i5 + mov 0,%i4 + addcc %g1,-1,%g1 + be .LL3 + mov %i5,%i4 + mov %i4,%i3 + mov 0,%i2 + ld [%g4-4],%g2 + mov %g2,%i1 + ld [%o7-4],%g2 + mov 0,%i0 + umul %o1,%g2,%g3 + rd %y,%g2 + addcc %g3,%i1,%g3 + addx %g2,%i0,%g2 + addcc %g3,%i3,%g3 + addx %g2,%i2,%g2 + st %g3,[%g4-4] + mov %g2,%i5 + mov 0,%i4 + addcc %g1,-1,%g1 + be .LL3 + mov %i5,%i4 + mov %i4,%i3 + mov 0,%i2 + ld [%g4],%g2 + mov %g2,%i1 + ld [%o7],%g2 + mov 0,%i0 + umul %o1,%g2,%g3 + rd %y,%g2 + addcc %g3,%i1,%g3 + addx %g2,%i0,%g2 + addcc %g3,%i3,%g3 + addx %g2,%i2,%g2 + st %g3,[%g4] + mov %g2,%i5 + mov 0,%i4 + addcc %g1,-1,%g1 + be .LL3 + mov %i5,%i4 + add %o7,16,%o7 + add %o2,16,%o2 + add %g4,16,%g4 + b .LL2 + add %o0,16,%o0 +.LL3: + ret + restore %g0,%i4,%o0 +.LLfe1: + .size bn_mul_add_word,.LLfe1-bn_mul_add_word + .align 4 + .global bn_mul_word + .type bn_mul_word,#function + .proc 016 +bn_mul_word: + !#PROLOGUE# 0 + save %sp,-112,%sp + !#PROLOGUE# 1 + mov %i0,%o7 + mov %i1,%o0 + mov %i2,%i4 + mov %i3,%g4 + mov 0,%i0 + add %o7,12,%g1 + add %o0,12,%i5 +.LL18: + mov %i0,%g3 + mov 0,%g2 + ld [%o0],%i2 + umul %g4,%i2,%i3 + rd %y,%i2 + addcc %i3,%g3,%i3 + addx %i2,%g2,%i2 + st %i3,[%o7] + mov %i2,%i1 + mov 0,%i0 + addcc %i4,-1,%i4 + be .LL19 + mov %i1,%i0 + mov %i0,%g3 + mov 0,%g2 + ld [%i5-8],%i2 + umul %g4,%i2,%i3 + rd %y,%i2 + addcc %i3,%g3,%i3 + addx %i2,%g2,%i2 + st %i3,[%g1-8] + mov %i2,%i1 + mov 0,%i0 + addcc %i4,-1,%i4 + be .LL19 + mov %i1,%i0 + mov %i0,%g3 + mov 0,%g2 + ld [%i5-4],%i2 + umul %g4,%i2,%i3 + rd %y,%i2 + addcc %i3,%g3,%i3 + addx %i2,%g2,%i2 + st %i3,[%g1-4] + mov %i2,%i1 + mov 0,%i0 + addcc %i4,-1,%i4 + be .LL19 + mov %i1,%i0 + mov %i0,%g3 + mov 0,%g2 + ld [%i5],%i2 + umul %g4,%i2,%i3 + rd %y,%i2 + addcc %i3,%g3,%i3 + addx %i2,%g2,%i2 + st %i3,[%g1] + mov %i2,%i1 + mov 0,%i0 + addcc %i4,-1,%i4 + be .LL19 + mov %i1,%i0 + add %i5,16,%i5 + add %o0,16,%o0 + add %g1,16,%g1 + b .LL18 + add %o7,16,%o7 +.LL19: + ret + restore +.LLfe2: + .size bn_mul_word,.LLfe2-bn_mul_word + .align 4 + .global bn_sqr_words + .type bn_sqr_words,#function + .proc 020 +bn_sqr_words: + !#PROLOGUE# 0 + !#PROLOGUE# 1 + mov %o0,%g4 + add %g4,28,%o3 + add %o1,12,%g1 +.LL34: + ld [%o1],%o0 + addcc %o2,-1,%o2 + umul %o0,%o0,%o5 + rd %y,%o4 + st %o5,[%g4] + mov %o4,%g3 + mov 0,%g2 + be .LL35 + st %g3,[%o3-24] + ld [%g1-8],%o0 + addcc %o2,-1,%o2 + umul %o0,%o0,%o5 + rd %y,%o4 + st %o5,[%o3-20] + mov %o4,%g3 + mov 0,%g2 + be .LL35 + st %g3,[%o3-16] + ld [%g1-4],%o0 + addcc %o2,-1,%o2 + umul %o0,%o0,%o5 + rd %y,%o4 + st %o5,[%o3-12] + mov %o4,%g3 + mov 0,%g2 + be .LL35 + st %g3,[%o3-8] + ld [%g1],%o0 + addcc %o2,-1,%o2 + umul %o0,%o0,%o5 + rd %y,%o4 + st %o5,[%o3-4] + mov %o4,%g3 + mov 0,%g2 + be .LL35 + st %g3,[%o3] + add %g1,16,%g1 + add %o1,16,%o1 + add %o3,32,%o3 + b .LL34 + add %g4,32,%g4 +.LL35: + retl + nop +.LLfe3: + .size bn_sqr_words,.LLfe3-bn_sqr_words +.section ".rodata" + .align 8 +.LLC0: + .asciz "Division would overflow\n" +.section ".text" + .align 4 + .global bn_div64 + .type bn_div64,#function + .proc 016 +bn_div64: + !#PROLOGUE# 0 + save %sp,-112,%sp + !#PROLOGUE# 1 + mov 0,%l1 + cmp %i2,0 + bne .LL42 + mov 2,%l0 + b .LL59 + mov -1,%i0 +.LL42: + call BN_num_bits_word,0 + mov %i2,%o0 + mov %o0,%o2 + cmp %o2,32 + be .LL43 + mov 1,%o0 + sll %o0,%o2,%o0 + cmp %i0,%o0 + bleu .LL60 + mov 32,%o0 + sethi %hi(__iob+32),%o0 + or %o0,%lo(__iob+32),%o0 + sethi %hi(.LLC0),%o1 + call fprintf,0 + or %o1,%lo(.LLC0),%o1 + call abort,0 + nop +.LL43: + mov 32,%o0 +.LL60: + cmp %i0,%i2 + blu .LL44 + sub %o0,%o2,%o2 + sub %i0,%i2,%i0 +.LL44: + cmp %o2,0 + be .LL45 + sethi %hi(-65536),%o7 + sll %i2,%o2,%i2 + sll %i0,%o2,%o1 + sub %o0,%o2,%o0 + srl %i1,%o0,%o0 + or %o1,%o0,%i0 + sll %i1,%o2,%i1 +.LL45: + srl %i2,16,%g2 + sethi %hi(65535),%o0 + or %o0,%lo(65535),%o1 + and %i2,%o1,%g3 + mov %o0,%g4 + mov %o1,%g1 +.LL46: + srl %i0,16,%o0 + cmp %o0,%g2 + be .LL50 + or %g4,%lo(65535),%o3 + wr %g0,%g0,%y + nop + nop + nop + udiv %i0,%g2,%o3 +.LL50: + and %i1,%o7,%o0 + srl %o0,16,%o5 + smul %o3,%g3,%o4 + smul %o3,%g2,%o2 +.LL51: + sub %i0,%o2,%o1 + andcc %o1,%o7,%g0 + bne .LL52 + sll %o1,16,%o0 + add %o0,%o5,%o0 + cmp %o4,%o0 + bleu .LL52 + sub %o4,%g3,%o4 + sub %o2,%g2,%o2 + b .LL51 + add %o3,-1,%o3 +.LL52: + smul %o3,%g2,%o2 + smul %o3,%g3,%o0 + srl %o0,16,%o1 + sll %o0,16,%o0 + and %o0,%o7,%o0 + cmp %i1,%o0 + bgeu .LL56 + add %o2,%o1,%o2 + add %o2,1,%o2 +.LL56: + cmp %i0,%o2 + bgeu .LL57 + sub %i1,%o0,%i1 + add %i0,%i2,%i0 + add %o3,-1,%o3 +.LL57: + addcc %l0,-1,%l0 + be .LL47 + sub %i0,%o2,%i0 + sll %o3,16,%l1 + sll %i0,16,%o0 + srl %i1,16,%o1 + or %o0,%o1,%i0 + and %i1,%g1,%o0 + b .LL46 + sll %o0,16,%i1 +.LL47: + or %l1,%o3,%i0 +.LL59: + ret + restore +.LLfe4: + .size bn_div64,.LLfe4-bn_div64 + .ident "GCC: (GNU) 2.7.0" diff --git a/crypto/bn/asm/x86-bsdi.s b/crypto/bn/asm/x86-bsdi.s new file mode 100644 index 0000000000..ca6687648e --- /dev/null +++ b/crypto/bn/asm/x86-bsdi.s @@ -0,0 +1,272 @@ + .file "bn_mulw.c" + .version "01.01" +gcc2_compiled.: +.text + .align 4 +.globl _bn_mul_add_word +_bn_mul_add_word: + pushl %ebp + pushl %edi + pushl %esi + pushl %ebx + + # ax L(t) + # dx H(t) + # bx a + # cx w + # di r + # si c + # bp num + xorl %esi,%esi # c=0 + movl 20(%esp),%edi # r => edi + movl 24(%esp),%ebx # a => exb + movl 32(%esp),%ecx # w => ecx + movl 28(%esp),%ebp # num => ebp + + shrl $2,%ebp # num/4 + je .L910 + +# .align 4 +.L110: + # Round 1 + movl %ecx,%eax # w => eax + mull (%ebx) # w * *a + addl (%edi),%eax # *r+=L(t) + adcl $0,%edx # H(t)+= carry + addl %esi,%eax # L(t)+=c + adcl $0,%edx # H(t)+=carry + movl %eax,(%edi) # *r+=L(t) + movl %edx,%esi # c=H(t) + + # Round 2 + movl %ecx,%eax # w => eax + mull 4(%ebx) # w * *a + addl 4(%edi),%eax # *r+=L(t) + adcl $0,%edx # H(t)+= carry + addl %esi,%eax # L(t)+=c + adcl $0,%edx # H(t)+=carry + movl %eax,4(%edi) # *r+=L(t) + movl %edx,%esi # c=H(t) + + # Round 3 + movl %ecx,%eax # w => eax + mull 8(%ebx) # w * *a + addl 8(%edi),%eax # *r+=L(t) + adcl $0,%edx # H(t)+=carry + addl %esi,%eax # L(t)+=c + adcl $0,%edx # H(t)+=carry + movl %eax,8(%edi) # *r+=L(t) + movl %edx,%esi # c=H(t) + + # Round 4 + movl %ecx,%eax # w => eax + mull 12(%ebx) # w * *a + addl 12(%edi),%eax # *r+=L(t) + adcl $0,%edx # H(t)+=carry + addl %esi,%eax # L(t)+=c + adcl $0,%edx # H(t)+=carry + movl %eax,12(%edi) # *r+=L(t) + movl %edx,%esi # c=H(t) + + addl $16,%ebx # a+=4 (4 words) + addl $16,%edi # r+=4 (4 words) + + decl %ebp # --num + je .L910 + jmp .L110 +# .align 4 +.L910: + movl 28(%esp),%ebp # num => ebp + andl $3,%ebp + je .L111 + + # Round 1 + movl %ecx,%eax # w => eax + mull (%ebx) # w * *a + addl (%edi),%eax # *r+=L(t) + adcl $0,%edx # H(t)+=carry + addl %esi,%eax # L(t)+=c + adcl $0,%edx # H(t)+=carry + movl %eax,(%edi) # *r+=L(t) + movl %edx,%esi # c=H(t) + decl %ebp # --num + je .L111 + + # Round 2 + movl %ecx,%eax # w => eax + mull 4(%ebx) # w * *a + addl 4(%edi),%eax # *r+=L(t) + adcl $0,%edx # H(t)+=carry + addl %esi,%eax # L(t)+=c + adcl $0,%edx # H(t)+=carry + movl %eax,4(%edi) # *r+=L(t) + movl %edx,%esi # c=H(t) + decl %ebp # --num + je .L111 + + # Round 3 + movl %ecx,%eax # w => eax + mull 8(%ebx) # w * *a + addl 8(%edi),%eax # *r+=L(t) + adcl $0,%edx # H(t)+=carry + addl %esi,%eax # L(t)+=c + adcl $0,%edx # H(t)+=carry + movl %eax,8(%edi) # *r+=L(t) + movl %edx,%esi # c=H(t) + +# .align 4 +.L111: + movl %esi,%eax # return(c) + popl %ebx + popl %esi + popl %edi + popl %ebp + ret +.Lfe1: + .align 4 +.globl _bn_mul_word +_bn_mul_word: + pushl %ebp + pushl %edi + pushl %esi + pushl %ebx + + # ax L(t) + # dx H(t) + # bx a + # cx w + # di r + # num bp + # si c + xorl %esi,%esi # c=0 + movl 20(%esp),%edi # r => edi + movl 24(%esp),%ebx # a => exb + movl 28(%esp),%ebp # num => bp + movl 32(%esp),%ecx # w => ecx + +# .align 4 +.L210: + movl %ecx,%eax # w => eax + mull (%ebx) # w * *a + addl %esi,%eax # L(t)+=c + adcl $0,%edx # H(t)+=carry + movl %eax,(%edi) # *r=L(t) + movl %edx,%esi # c=H(t) + decl %ebp # --num + je .L211 + + movl %ecx,%eax # w => eax + mull 4(%ebx) # w * *a + addl %esi,%eax # L(t)+=c + adcl $0,%edx # H(t)+=carry + movl %eax,4(%edi) # *r=L(t) + movl %edx,%esi # c=H(t) + decl %ebp # --num + je .L211 + + movl %ecx,%eax # w => eax + mull 8(%ebx) # w * *a + addl %esi,%eax # L(t)+=c + adcl $0,%edx # H(t)+=carry + movl %eax,8(%edi) # *r=L(t) + movl %edx,%esi # c=H(t) + decl %ebp # --num + je .L211 + + movl %ecx,%eax # w => eax + mull 12(%ebx) # w * *a + addl %esi,%eax # L(t)+=c + adcl $0,%edx # H(t)+=carry + movl %eax,12(%edi) # *r=L(t) + movl %edx,%esi # c=H(t) + decl %ebp # --num + je .L211 + + addl $16,%ebx # a+=4 (4 words) + addl $16,%edi # r+=4 (4 words) + + jmp .L210 +# .align 4 +.L211: + movl %esi,%eax # return(c) + popl %ebx + popl %esi + popl %edi + popl %ebp + ret +.Lfe2: + .align 4 +.globl _bn_sqr_words +_bn_sqr_words: + pushl %edi + pushl %esi + pushl %ebx + movl 16(%esp),%esi # r + movl 20(%esp),%edi # a + movl 24(%esp),%ebx # n +# .align 4 + shrl $2,%ebx + jz .L99 +.L28: + movl (%edi),%eax # get a + mull %eax # a*a + movl %eax,(%esi) # put low into return addr + movl %edx,4(%esi) # put high into return addr + + movl 4(%edi),%eax # get a + mull %eax # a*a + movl %eax,8(%esi) # put low into return addr + movl %edx,12(%esi) # put high into return addr + + movl 8(%edi),%eax # get a + mull %eax # a*a + movl %eax,16(%esi) # put low into return addr + movl %edx,20(%esi) # put high into return addr + + movl 12(%edi),%eax # get a + mull %eax # a*a + movl %eax,24(%esi) # put low into return addr + movl %edx,28(%esi) # put high into return addr + + addl $16,%edi + addl $32,%esi + decl %ebx # n-=4; + jz .L99 + jmp .L28 +# .align 4 +.L99: + movl 24(%esp),%ebx # n + andl $3,%ebx + jz .L29 + movl (%edi),%eax # get a + mull %eax # a*a + movl %eax,(%esi) # put low into return addr + movl %edx,4(%esi) # put high into return addr + decl %ebx # n--; + jz .L29 + movl 4(%edi),%eax # get a + mull %eax # a*a + movl %eax,8(%esi) # put low into return addr + movl %edx,12(%esi) # put high into return addr + decl %ebx # n--; + jz .L29 + movl 8(%edi),%eax # get a + mull %eax # a*a + movl %eax,16(%esi) # put low into return addr + movl %edx,20(%esi) # put high into return addr + +.L29: + popl %ebx + popl %esi + popl %edi + ret +.Lfe3: + .align 4 +.globl _bn_div64 +_bn_div64: + movl 4(%esp),%edx # a + movl 8(%esp),%eax # b + divl 12(%esp) # ab/c + ret +.Lfe4: + .ident "GCC: (GNU) 2.6.3" diff --git a/crypto/bn/asm/x86-lnx.s b/crypto/bn/asm/x86-lnx.s new file mode 100644 index 0000000000..5123867440 --- /dev/null +++ b/crypto/bn/asm/x86-lnx.s @@ -0,0 +1,282 @@ + .file "bn_mulw.c" + .version "01.01" +gcc2_compiled.: +.text + .align 16 +.globl bn_mul_add_word + .type bn_mul_add_word,@function +bn_mul_add_word: + pushl %ebp + pushl %edi + pushl %esi + pushl %ebx + + # ax L(t) + # dx H(t) + # bx a + # cx w + # di r + # si c + # bp num + xorl %esi,%esi # c=0 + movl 20(%esp),%edi # r => edi + movl 24(%esp),%ebx # a => exb + movl 32(%esp),%ecx # w => ecx + movl 28(%esp),%ebp # num => ebp + + shrl $2,%ebp # num/4 + je .L910 + + .align 4 +.L110: + # Round 1 + movl %ecx,%eax # w => eax + mull (%ebx) # w * *a + addl (%edi),%eax # *r+=L(t) + adcl $0,%edx # H(t)+= carry + addl %esi,%eax # L(t)+=c + adcl $0,%edx # H(t)+=carry + movl %eax,(%edi) # *r+=L(t) + movl %edx,%esi # c=H(t) + + # Round 2 + movl %ecx,%eax # w => eax + mull 4(%ebx) # w * *a + addl 4(%edi),%eax # *r+=L(t) + adcl $0,%edx # H(t)+= carry + addl %esi,%eax # L(t)+=c + adcl $0,%edx # H(t)+=carry + movl %eax,4(%edi) # *r+=L(t) + movl %edx,%esi # c=H(t) + + # Round 3 + movl %ecx,%eax # w => eax + mull 8(%ebx) # w * *a + addl 8(%edi),%eax # *r+=L(t) + adcl $0,%edx # H(t)+=carry + addl %esi,%eax # L(t)+=c + adcl $0,%edx # H(t)+=carry + movl %eax,8(%edi) # *r+=L(t) + movl %edx,%esi # c=H(t) + + # Round 4 + movl %ecx,%eax # w => eax + mull 12(%ebx) # w * *a + addl 12(%edi),%eax # *r+=L(t) + adcl $0,%edx # H(t)+=carry + addl %esi,%eax # L(t)+=c + adcl $0,%edx # H(t)+=carry + movl %eax,12(%edi) # *r+=L(t) + movl %edx,%esi # c=H(t) + + addl $16,%ebx # a+=4 (4 words) + addl $16,%edi # r+=4 (4 words) + + decl %ebp # --num + je .L910 + jmp .L110 + .align 4 +.L910: + movl 28(%esp),%ebp # num => ebp + andl $3,%ebp + je .L111 + + # Round 1 + movl %ecx,%eax # w => eax + mull (%ebx) # w * *a + addl (%edi),%eax # *r+=L(t) + adcl $0,%edx # H(t)+=carry + addl %esi,%eax # L(t)+=c + adcl $0,%edx # H(t)+=carry + movl %eax,(%edi) # *r+=L(t) + movl %edx,%esi # c=H(t) + decl %ebp # --num + je .L111 + + # Round 2 + movl %ecx,%eax # w => eax + mull 4(%ebx) # w * *a + addl 4(%edi),%eax # *r+=L(t) + adcl $0,%edx # H(t)+=carry + addl %esi,%eax # L(t)+=c + adcl $0,%edx # H(t)+=carry + movl %eax,4(%edi) # *r+=L(t) + movl %edx,%esi # c=H(t) + decl %ebp # --num + je .L111 + + # Round 3 + movl %ecx,%eax # w => eax + mull 8(%ebx) # w * *a + addl 8(%edi),%eax # *r+=L(t) + adcl $0,%edx # H(t)+=carry + addl %esi,%eax # L(t)+=c + adcl $0,%edx # H(t)+=carry + movl %eax,8(%edi) # *r+=L(t) + movl %edx,%esi # c=H(t) + + .align 4 +.L111: + movl %esi,%eax # return(c) + popl %ebx + popl %esi + popl %edi + popl %ebp + ret +.Lfe1: + .size bn_mul_add_word,.Lfe1-bn_mul_add_word + .align 16 +.globl bn_mul_word + .type bn_mul_word,@function +bn_mul_word: + pushl %ebp + pushl %edi + pushl %esi + pushl %ebx + + # ax L(t) + # dx H(t) + # bx a + # cx w + # di r + # num bp + # si c + xorl %esi,%esi # c=0 + movl 20(%esp),%edi # r => edi + movl 24(%esp),%ebx # a => exb + movl 28(%esp),%ebp # num => bp + movl 32(%esp),%ecx # w => ecx + + .align 4 +.L210: + movl %ecx,%eax # w => eax + mull (%ebx) # w * *a + addl %esi,%eax # L(t)+=c + adcl $0,%edx # H(t)+=carry + movl %eax,(%edi) # *r=L(t) + movl %edx,%esi # c=H(t) + decl %ebp # --num + je .L211 + + movl %ecx,%eax # w => eax + mull 4(%ebx) # w * *a + addl %esi,%eax # L(t)+=c + adcl $0,%edx # H(t)+=carry + movl %eax,4(%edi) # *r=L(t) + movl %edx,%esi # c=H(t) + decl %ebp # --num + je .L211 + + movl %ecx,%eax # w => eax + mull 8(%ebx) # w * *a + addl %esi,%eax # L(t)+=c + adcl $0,%edx # H(t)+=carry + movl %eax,8(%edi) # *r=L(t) + movl %edx,%esi # c=H(t) + decl %ebp # --num + je .L211 + + movl %ecx,%eax # w => eax + mull 12(%ebx) # w * *a + addl %esi,%eax # L(t)+=c + adcl $0,%edx # H(t)+=carry + movl %eax,12(%edi) # *r=L(t) + movl %edx,%esi # c=H(t) + decl %ebp # --num + je .L211 + + addl $16,%ebx # a+=4 (4 words) + addl $16,%edi # r+=4 (4 words) + + jmp .L210 + .align 16 +.L211: + movl %esi,%eax # return(c) + popl %ebx + popl %esi + popl %edi + popl %ebp + ret +.Lfe2: + .size bn_mul_word,.Lfe2-bn_mul_word + + .align 16 +.globl bn_sqr_words + .type bn_sqr_words,@function +bn_sqr_words: + pushl %edi + pushl %esi + pushl %ebx + movl 16(%esp),%esi # r + movl 20(%esp),%edi # a + movl 24(%esp),%ebx # n + .align 4 + shrl $2,%ebx + jz .L99 +.L28: + movl (%edi),%eax # get a + mull %eax # a*a + movl %eax,(%esi) # put low into return addr + movl %edx,4(%esi) # put high into return addr + + movl 4(%edi),%eax # get a + mull %eax # a*a + movl %eax,8(%esi) # put low into return addr + movl %edx,12(%esi) # put high into return addr + + movl 8(%edi),%eax # get a + mull %eax # a*a + movl %eax,16(%esi) # put low into return addr + movl %edx,20(%esi) # put high into return addr + + movl 12(%edi),%eax # get a + mull %eax # a*a + movl %eax,24(%esi) # put low into return addr + movl %edx,28(%esi) # put high into return addr + + addl $16,%edi + addl $32,%esi + decl %ebx # n-=4; + jz .L99 + jmp .L28 + .align 16 +.L99: + movl 24(%esp),%ebx # n + andl $3,%ebx + jz .L29 + movl (%edi),%eax # get a + mull %eax # a*a + movl %eax,(%esi) # put low into return addr + movl %edx,4(%esi) # put high into return addr + decl %ebx # n--; + jz .L29 + movl 4(%edi),%eax # get a + mull %eax # a*a + movl %eax,8(%esi) # put low into return addr + movl %edx,12(%esi) # put high into return addr + decl %ebx # n--; + jz .L29 + movl 8(%edi),%eax # get a + mull %eax # a*a + movl %eax,16(%esi) # put low into return addr + movl %edx,20(%esi) # put high into return addr + +.L29: + popl %ebx + popl %esi + popl %edi + ret +.Lfe3: + .size bn_sqr_words,.Lfe3-bn_sqr_words + + .align 16 +.globl bn_div64 + .type bn_div64,@function +bn_div64: + movl 4(%esp),%edx # a + movl 8(%esp),%eax # b + divl 12(%esp) # ab/c + ret +.Lfe4: + .size bn_div64,.Lfe4-bn_div64 + .ident "GCC: (GNU) 2.6.3" diff --git a/crypto/bn/asm/x86-lnxa.s b/crypto/bn/asm/x86-lnxa.s new file mode 100644 index 0000000000..74855dc74d --- /dev/null +++ b/crypto/bn/asm/x86-lnxa.s @@ -0,0 +1,282 @@ + .file "bn_mulw.c" + .version "01.01" +gcc2_compiled.: +.text + .align 4 +.globl _bn_mul_add_word + .type _bn_mul_add_word,@function +_bn_mul_add_word: + pushl %ebp + pushl %edi + pushl %esi + pushl %ebx + + # ax L(t) + # dx H(t) + # bx a + # cx w + # di r + # si c + # bp num + xorl %esi,%esi # c=0 + movl 20(%esp),%edi # r => edi + movl 24(%esp),%ebx # a => exb + movl 32(%esp),%ecx # w => ecx + movl 28(%esp),%ebp # num => ebp + + shrl $2,%ebp # num/4 + je .L910 + +# .align 4 +.L110: + # Round 1 + movl %ecx,%eax # w => eax + mull (%ebx) # w * *a + addl (%edi),%eax # *r+=L(t) + adcl $0,%edx # H(t)+= carry + addl %esi,%eax # L(t)+=c + adcl $0,%edx # H(t)+=carry + movl %eax,(%edi) # *r+=L(t) + movl %edx,%esi # c=H(t) + + # Round 2 + movl %ecx,%eax # w => eax + mull 4(%ebx) # w * *a + addl 4(%edi),%eax # *r+=L(t) + adcl $0,%edx # H(t)+= carry + addl %esi,%eax # L(t)+=c + adcl $0,%edx # H(t)+=carry + movl %eax,4(%edi) # *r+=L(t) + movl %edx,%esi # c=H(t) + + # Round 3 + movl %ecx,%eax # w => eax + mull 8(%ebx) # w * *a + addl 8(%edi),%eax # *r+=L(t) + adcl $0,%edx # H(t)+=carry + addl %esi,%eax # L(t)+=c + adcl $0,%edx # H(t)+=carry + movl %eax,8(%edi) # *r+=L(t) + movl %edx,%esi # c=H(t) + + # Round 4 + movl %ecx,%eax # w => eax + mull 12(%ebx) # w * *a + addl 12(%edi),%eax # *r+=L(t) + adcl $0,%edx # H(t)+=carry + addl %esi,%eax # L(t)+=c + adcl $0,%edx # H(t)+=carry + movl %eax,12(%edi) # *r+=L(t) + movl %edx,%esi # c=H(t) + + addl $16,%ebx # a+=4 (4 words) + addl $16,%edi # r+=4 (4 words) + + decl %ebp # --num + je .L910 + jmp .L110 +# .align 4 +.L910: + movl 28(%esp),%ebp # num => ebp + andl $3,%ebp + je .L111 + + # Round 1 + movl %ecx,%eax # w => eax + mull (%ebx) # w * *a + addl (%edi),%eax # *r+=L(t) + adcl $0,%edx # H(t)+=carry + addl %esi,%eax # L(t)+=c + adcl $0,%edx # H(t)+=carry + movl %eax,(%edi) # *r+=L(t) + movl %edx,%esi # c=H(t) + decl %ebp # --num + je .L111 + + # Round 2 + movl %ecx,%eax # w => eax + mull 4(%ebx) # w * *a + addl 4(%edi),%eax # *r+=L(t) + adcl $0,%edx # H(t)+=carry + addl %esi,%eax # L(t)+=c + adcl $0,%edx # H(t)+=carry + movl %eax,4(%edi) # *r+=L(t) + movl %edx,%esi # c=H(t) + decl %ebp # --num + je .L111 + + # Round 3 + movl %ecx,%eax # w => eax + mull 8(%ebx) # w * *a + addl 8(%edi),%eax # *r+=L(t) + adcl $0,%edx # H(t)+=carry + addl %esi,%eax # L(t)+=c + adcl $0,%edx # H(t)+=carry + movl %eax,8(%edi) # *r+=L(t) + movl %edx,%esi # c=H(t) + +# .align 4 +.L111: + movl %esi,%eax # return(c) + popl %ebx + popl %esi + popl %edi + popl %ebp + ret +.Lfe1: + .size _bn_mul_add_word,.Lfe1-_bn_mul_add_word + .align 4 +.globl _bn_mul_word + .type _bn_mul_word,@function +_bn_mul_word: + pushl %ebp + pushl %edi + pushl %esi + pushl %ebx + + # ax L(t) + # dx H(t) + # bx a + # cx w + # di r + # num bp + # si c + xorl %esi,%esi # c=0 + movl 20(%esp),%edi # r => edi + movl 24(%esp),%ebx # a => exb + movl 28(%esp),%ebp # num => bp + movl 32(%esp),%ecx # w => ecx + +# .align 4 +.L210: + movl %ecx,%eax # w => eax + mull (%ebx) # w * *a + addl %esi,%eax # L(t)+=c + adcl $0,%edx # H(t)+=carry + movl %eax,(%edi) # *r=L(t) + movl %edx,%esi # c=H(t) + decl %ebp # --num + je .L211 + + movl %ecx,%eax # w => eax + mull 4(%ebx) # w * *a + addl %esi,%eax # L(t)+=c + adcl $0,%edx # H(t)+=carry + movl %eax,4(%edi) # *r=L(t) + movl %edx,%esi # c=H(t) + decl %ebp # --num + je .L211 + + movl %ecx,%eax # w => eax + mull 8(%ebx) # w * *a + addl %esi,%eax # L(t)+=c + adcl $0,%edx # H(t)+=carry + movl %eax,8(%edi) # *r=L(t) + movl %edx,%esi # c=H(t) + decl %ebp # --num + je .L211 + + movl %ecx,%eax # w => eax + mull 12(%ebx) # w * *a + addl %esi,%eax # L(t)+=c + adcl $0,%edx # H(t)+=carry + movl %eax,12(%edi) # *r=L(t) + movl %edx,%esi # c=H(t) + decl %ebp # --num + je .L211 + + addl $16,%ebx # a+=4 (4 words) + addl $16,%edi # r+=4 (4 words) + + jmp .L210 +# .align 4 +.L211: + movl %esi,%eax # return(c) + popl %ebx + popl %esi + popl %edi + popl %ebp + ret +.Lfe2: + .size _bn_mul_word,.Lfe2-_bn_mul_word + + .align 4 +.globl _bn_sqr_words + .type _bn_sqr_words,@function +_bn_sqr_words: + pushl %edi + pushl %esi + pushl %ebx + movl 16(%esp),%esi # r + movl 20(%esp),%edi # a + movl 24(%esp),%ebx # n +# .align 4 + shrl $2,%ebx + jz .L99 +.L28: + movl (%edi),%eax # get a + mull %eax # a*a + movl %eax,(%esi) # put low into return addr + movl %edx,4(%esi) # put high into return addr + + movl 4(%edi),%eax # get a + mull %eax # a*a + movl %eax,8(%esi) # put low into return addr + movl %edx,12(%esi) # put high into return addr + + movl 8(%edi),%eax # get a + mull %eax # a*a + movl %eax,16(%esi) # put low into return addr + movl %edx,20(%esi) # put high into return addr + + movl 12(%edi),%eax # get a + mull %eax # a*a + movl %eax,24(%esi) # put low into return addr + movl %edx,28(%esi) # put high into return addr + + addl $16,%edi + addl $32,%esi + decl %ebx # n-=4; + jz .L99 + jmp .L28 +# .align 4 +.L99: + movl 24(%esp),%ebx # n + andl $3,%ebx + jz .L29 + movl (%edi),%eax # get a + mull %eax # a*a + movl %eax,(%esi) # put low into return addr + movl %edx,4(%esi) # put high into return addr + decl %ebx # n--; + jz .L29 + movl 4(%edi),%eax # get a + mull %eax # a*a + movl %eax,8(%esi) # put low into return addr + movl %edx,12(%esi) # put high into return addr + decl %ebx # n--; + jz .L29 + movl 8(%edi),%eax # get a + mull %eax # a*a + movl %eax,16(%esi) # put low into return addr + movl %edx,20(%esi) # put high into return addr + +.L29: + popl %ebx + popl %esi + popl %edi + ret +.Lfe3: + .size _bn_sqr_words,.Lfe3-_bn_sqr_words + + .align 4 +.globl _bn_div64 + .type _bn_div64,@function +_bn_div64: + movl 4(%esp),%edx # a + movl 8(%esp),%eax # b + divl 12(%esp) # ab/c + ret +.Lfe4: + .size _bn_div64,.Lfe4-_bn_div64 + .ident "GCC: (GNU) 2.6.3" diff --git a/crypto/bn/asm/x86-sol.s b/crypto/bn/asm/x86-sol.s new file mode 100644 index 0000000000..c961e64fa0 --- /dev/null +++ b/crypto/bn/asm/x86-sol.s @@ -0,0 +1,224 @@ + .file "bn_mulw.c" + .version "01.01" +gcc2_compiled.: +.text + .align 16 +.globl bn_mul_add_word + .type bn_mul_add_word,@function +bn_mul_add_word: + pushl %ebp + pushl %edi + pushl %esi + pushl %ebx + + / ax L(t) + / dx H(t) + / bx a + / cx w + / di r + / si c + / bp num + xorl %esi,%esi / c=0 + movl 20(%esp),%edi / r => edi + movl 24(%esp),%ebx / a => exb + movl 28(%esp),%ebp / num => ebp + movl 32(%esp),%ecx / w => ecx + + .align 4 +.L110: + movl %ecx,%eax / w => eax + mull (%ebx) / w * *a + addl (%edi),%eax / L(t)+= *r + adcl $0,%edx / H(t)+= carry + addl %esi,%eax / L(t)+=c + adcl $0,%edx / H(t)+=carry + movl %eax,(%edi) / *r=L(t) + movl %edx,%esi / c=H(t) + decl %ebp / --num + je .L111 + + movl %ecx,%eax / w => eax + mull 4(%ebx) / w * *a + addl 4(%edi),%eax / L(t)+= *r + adcl $0,%edx / H(t)+= carry + addl %esi,%eax / L(t)+=c + adcl $0,%edx / H(t)+=carry + movl %eax,4(%edi) / *r=L(t) + movl %edx,%esi / c=H(t) + decl %ebp / --num + je .L111 + + movl %ecx,%eax / w => eax + mull 8(%ebx) / w * *a + addl 8(%edi),%eax / L(t)+= *r + adcl $0,%edx / H(t)+= carry + addl %esi,%eax / L(t)+=c + adcl $0,%edx / H(t)+=carry + movl %eax,8(%edi) / *r=L(t) + movl %edx,%esi / c=H(t) + decl %ebp / --num + je .L111 + + movl %ecx,%eax / w => eax + mull 12(%ebx) / w * *a + addl 12(%edi),%eax / L(t)+= *r + adcl $0,%edx / H(t)+= carry + addl %esi,%eax / L(t)+=c + adcl $0,%edx / H(t)+=carry + movl %eax,12(%edi) / *r=L(t) + movl %edx,%esi / c=H(t) + decl %ebp / --num + je .L111 + + addl $16,%ebx / a+=4 (4 words) + addl $16,%edi / r+=4 (4 words) + + jmp .L110 + .align 16 +.L111: + movl %esi,%eax / return(c) + popl %ebx + popl %esi + popl %edi + popl %ebp + ret +.Lfe1: + .size bn_mul_add_word,.Lfe1-bn_mul_add_word + .align 16 +.globl bn_mul_word + .type bn_mul_word,@function +bn_mul_word: + pushl %ebp + pushl %edi + pushl %esi + pushl %ebx + + / ax L(t) + / dx H(t) + / bx a + / cx w + / di r + / num bp + / si c + xorl %esi,%esi / c=0 + movl 20(%esp),%edi / r => edi + movl 24(%esp),%ebx / a => exb + movl 28(%esp),%ebp / num => ebp + movl 32(%esp),%ecx / w => ecx + + .align 4 +.L210: + movl %ecx,%eax / w => eax + mull (%ebx) / w * *a + addl %esi,%eax / L(t)+=c + adcl $0,%edx / H(t)+=carry + movl %eax,(%edi) / *r=L(t) + movl %edx,%esi / c=H(t) + decl %ebp / --num + je .L211 + + movl %ecx,%eax / w => eax + mull 4(%ebx) / w * *a + addl %esi,%eax / L(t)+=c + adcl $0,%edx / H(t)+=carry + movl %eax,4(%edi) / *r=L(t) + movl %edx,%esi / c=H(t) + decl %ebp / --num + je .L211 + + movl %ecx,%eax / w => eax + mull 8(%ebx) / w * *a + addl %esi,%eax / L(t)+=c + adcl $0,%edx / H(t)+=carry + movl %eax,8(%edi) / *r=L(t) + movl %edx,%esi / c=H(t) + decl %ebp / --num + je .L211 + + movl %ecx,%eax / w => eax + mull 12(%ebx) / w * *a + addl %esi,%eax / L(t)+=c + adcl $0,%edx / H(t)+=carry + movl %eax,12(%edi) / *r=L(t) + movl %edx,%esi / c=H(t) + decl %ebp / --num + je .L211 + + addl $16,%ebx / a+=4 (4 words) + addl $16,%edi / r+=4 (4 words) + + jmp .L210 + .align 16 +.L211: + movl %esi,%eax / return(c) + popl %ebx + popl %esi + popl %edi + popl %ebp + ret +.Lfe2: + .size bn_mul_word,.Lfe2-bn_mul_word + + .align 16 +.globl bn_sqr_words + .type bn_sqr_words,@function +bn_sqr_words: + pushl %edi + pushl %esi + pushl %ebx + movl 16(%esp),%esi / r + movl 20(%esp),%edi / a + movl 24(%esp),%ebx / n + .align 4 +.L28: + movl (%edi),%eax / get a + mull %eax / a*a + movl %eax,(%esi) / put low into return addr + movl %edx,4(%esi) / put high into return addr + decl %ebx / n--; + je .L29 + + movl 4(%edi),%eax / get a + mull %eax / a*a + movl %eax,8(%esi) / put low into return addr + movl %edx,12(%esi) / put high into return addr + decl %ebx / n--; + je .L29 + + movl 8(%edi),%eax / get a + mull %eax / a*a + movl %eax,16(%esi) / put low into return addr + movl %edx,20(%esi) / put high into return addr + decl %ebx / n--; + je .L29 + + movl 12(%edi),%eax / get a + mull %eax / a*a + movl %eax,24(%esi) / put low into return addr + movl %edx,28(%esi) / put high into return addr + decl %ebx / n--; + je .L29 + + addl $16,%edi + addl $32,%esi + jmp .L28 + .align 16 +.L29: + popl %ebx + popl %esi + popl %edi + ret +.Lfe3: + .size bn_sqr_words,.Lfe3-bn_sqr_words + + .align 16 +.globl bn_div64 + .type bn_div64,@function +bn_div64: + movl 4(%esp),%edx / a + movl 8(%esp),%eax / b + divl 12(%esp) / ab/c + ret +.Lfe4: + .size bn_div64,.Lfe4-bn_div64 + .ident "GCC: (GNU) 2.6.3" diff --git a/crypto/bn/asm/x86nt32.asm b/crypto/bn/asm/x86nt32.asm new file mode 100644 index 0000000000..0198c2c583 --- /dev/null +++ b/crypto/bn/asm/x86nt32.asm @@ -0,0 +1,288 @@ + TITLE bn_mulw.c + .386P +.model FLAT +PUBLIC _bn_mul_add_word +_TEXT SEGMENT +; File bn_mulw.c +_bn_mul_add_word PROC NEAR + push ebp + push ebx + push esi + push edi + mov edi,DWORD PTR 20[esp] ; r + mov ebx,DWORD PTR 24[esp] ; a + mov ecx,DWORD PTR 32[esp] ; w + xor esi,esi ; c=0 + + mov ebp,DWORD PTR 28[esp] ; num + shr ebp,2 ; num/4 + jz $L666 + +$L546: + ; Round one + mov eax,DWORD PTR [ebx] ; edx:eax = *a * w + mul ecx + add eax,DWORD PTR [edi] ; *r+=ax + adc edx,0 + add eax,esi ; edx:eax += c + adc edx,0 + mov DWORD PTR [edi],eax ; *r+=ax + mov esi,edx ; c = overflow + + ; Round two + mov eax,DWORD PTR 4[ebx] ; edx:eax = *a * w + mul ecx + add eax,DWORD PTR 4[edi] ; *r+=ax + adc edx,0 + add eax,esi ; edx:eax += c + adc edx,0 + mov DWORD PTR 4[edi],eax ; *r+=ax + mov esi,edx ; c = overflow + + ; Round three + mov eax,DWORD PTR 8[ebx] ; edx:eax = *a * w + mul ecx + add eax,DWORD PTR 8[edi] ; *r+=ax + adc edx,0 + add eax,esi ; edx:eax += c + adc edx,0 + mov DWORD PTR 8[edi],eax ; *r+=ax + mov esi,edx ; c = overflow + + ; Round four + mov eax,DWORD PTR 12[ebx] ; edx:eax = *a * w + mul ecx + add eax,DWORD PTR 12[edi] ; *r+=ax + adc edx,0 + add eax,esi ; edx:eax += c + adc edx,0 + mov DWORD PTR 12[edi],eax ; *r+=ax + mov esi,edx ; c = overflow + + add ebx,16 + add edi,16 + + dec ebp + jz $L666 + jmp $L546 +$L666: + mov ebp,DWORD PTR 28[esp] ; num + and ebp,3 ; num%4 + jz $L547 + + ; Round one + mov eax,DWORD PTR [ebx] ; edx:eax = *a * w + mul ecx + add eax,DWORD PTR [edi] ; *r+=ax + adc edx,0 + add eax,esi ; edx:eax += c + adc edx,0 + mov DWORD PTR [edi],eax ; *r+=ax + mov esi,edx ; c = overflow + dec ebp + jz $L547 + ; Round two + mov eax,DWORD PTR 4[ebx] ; edx:eax = *a * w + mul ecx + add eax,DWORD PTR 4[edi] ; *r+=ax + adc edx,0 + add eax,esi ; edx:eax += c + adc edx,0 + mov DWORD PTR 4[edi],eax ; *r+=ax + mov esi,edx ; c = overflow + dec ebp + jz $L547 + ; Round three + mov eax,DWORD PTR 8[ebx] ; edx:eax = *a * w + mul ecx + add eax,DWORD PTR 8[edi] ; *r+=ax + adc edx,0 + add eax,esi ; edx:eax += c + adc edx,0 + mov DWORD PTR 8[edi],eax ; *r+=ax + mov esi,edx ; c = overflow + +$L547: + mov eax,esi + pop edi + pop esi + pop ebx + pop ebp + ret +_bn_mul_add_word ENDP +_TEXT ENDS +PUBLIC _bn_mul_word +_TEXT SEGMENT +_bn_mul_word PROC NEAR + push ebp + push ebx + push esi + push edi + + mov edi,DWORD PTR 20[esp] ; r + mov ebx,DWORD PTR 24[esp] ; a + mov ebp,DWORD PTR 28[esp] ; num + mov ecx,DWORD PTR 32[esp] ; w + xor esi,esi ; c=0 + + shr ebp,2 ; num/4 + jz $L266 + +$L593: + ; Round one + mov eax,DWORD PTR [ebx] ; edx:eax= w * *a + mul ecx + add eax,esi ; edx:eax+=c + adc edx,0 + mov DWORD PTR [edi],eax ; *r=eax + mov esi,edx ; c=edx + ; Round two + mov eax,DWORD PTR 4[ebx] ; edx:eax= w * *a + mul ecx + add eax,esi ; edx:eax+=c + adc edx,0 + mov DWORD PTR 4[edi],eax ; *r=eax + mov esi,edx ; c=edx + ; Round three + mov eax,DWORD PTR 8[ebx] ; edx:eax= w * *a + mul ecx + add eax,esi ; edx:eax+=c + adc edx,0 + mov DWORD PTR 8[edi],eax ; *r=eax + mov esi,edx ; c=edx + ; Round four + mov eax,DWORD PTR 12[ebx] ; edx:eax= w * *a + mul ecx + add eax,esi ; edx:eax+=c + adc edx,0 + mov DWORD PTR 12[edi],eax ; *r=eax + mov esi,edx ; c=edx + + add ebx,16 + add edi,16 + + dec ebp + jz $L266 + jmp $L593 +$L266: + mov ebp,DWORD PTR 28[esp] ; num + and ebp,3 + jz $L601 + + ; Round one + mov eax,DWORD PTR [ebx] ; edx:eax= w * *a + mul ecx + add eax,esi ; edx:eax+=c + adc edx,0 + mov DWORD PTR [edi],eax ; *r=eax + mov esi,edx ; c=edx + dec ebp + jz $L601 + ; Round two + mov eax,DWORD PTR 4[ebx] ; edx:eax= w * *a + mul ecx + add eax,esi ; edx:eax+=c + adc edx,0 + mov DWORD PTR 4[edi],eax ; *r=eax + mov esi,edx ; c=edx + dec ebp + jz $L601 + ; Round three + mov eax,DWORD PTR 8[ebx] ; edx:eax= w * *a + mul ecx + add eax,esi ; edx:eax+=c + adc edx,0 + mov DWORD PTR 8[edi],eax ; *r=eax + mov esi,edx ; c=edx + +$L601: + mov eax,esi + pop edi + pop esi + pop ebx + pop ebp + ret +_bn_mul_word ENDP +_TEXT ENDS +PUBLIC _bn_sqr_words +_TEXT SEGMENT +_bn_sqr_words PROC NEAR + push ebx + push esi + push edi + mov esi,DWORD PTR 16[esp] ; r + mov edi,DWORD PTR 20[esp] ; a + mov ebx,DWORD PTR 24[esp] ; num + + shr ebx,2 ; num/4 + jz $L111 +$L640: + ; Round 1 + mov eax, DWORD PTR [edi] + mul eax ; *a * *a + mov DWORD PTR [esi],eax + mov DWORD PTR 4[esi],edx + ; Round 2 + mov eax, DWORD PTR 4[edi] + mul eax ; *a * *a + mov DWORD PTR 8[esi],eax + mov DWORD PTR 12[esi],edx + ; Round 3 + mov eax, DWORD PTR 8[edi] + mul eax ; *a * *a + mov DWORD PTR 16[esi],eax + mov DWORD PTR 20[esi],edx + ; Round 4 + mov eax, DWORD PTR 12[edi] + mul eax ; *a * *a + mov DWORD PTR 24[esi],eax + mov DWORD PTR 28[esi],edx + + add edi,16 + add esi,32 + + dec ebx + jz $L111 + jmp $L640 +$L111: + mov ebx,DWORD PTR 24[esp] ; num + and ebx,3 ; num%3 + jz $L645 + + ; Round 1 + mov eax, DWORD PTR [edi] + mul eax ; *a * *a + mov DWORD PTR [esi],eax + mov DWORD PTR 4[esi],edx + dec ebx + jz $L645 + ; Round 2 + mov eax, DWORD PTR 4[edi] + mul eax ; *a * *a + mov DWORD PTR 8[esi],eax + mov DWORD PTR 12[esi],edx + dec ebx + jz $L645 + ; Round 3 + mov eax, DWORD PTR 8[edi] + mul eax ; *a * *a + mov DWORD PTR 16[esi],eax + mov DWORD PTR 20[esi],edx + +$L645: + pop edi + pop esi + pop ebx + ret +_bn_sqr_words ENDP +_TEXT ENDS +PUBLIC _bn_div64 +_TEXT SEGMENT +_bn_div64 PROC NEAR + mov edx, DWORD PTR 4[esp] + mov eax, DWORD PTR 8[esp] + div DWORD PTR 12[esp] + ret +_bn_div64 ENDP +_TEXT ENDS +END diff --git a/crypto/bn/asm/x86nt32.uu b/crypto/bn/asm/x86nt32.uu new file mode 100644 index 0000000000..99207987c1 --- /dev/null +++ b/crypto/bn/asm/x86nt32.uu @@ -0,0 +1,22 @@ +begin 640 x86nt32.obj +M3`$"`/H&DC-6`@``"P`````````N=&5X=```````````````\@$``&0````` +M```````````````@`#!@+F1A=&$```#R`0````````````!6`@`````````` +M````````0``PP%535E>+?"04BUPD&(M,)"`S]HML)!S![0)T7(L#]^$#!X/2 +M``/&@](`B0>+\HM#!/?A`T<$@](``\:#T@")1P2+\HM#"/?A`T<(@](``\:# +MT@")1PB+\HM##/?A`T<,@](``\:#T@")1PR+\H/#$(/'$$UT`NNDBVPD'(/E +M`W1"BP/WX0,'@](``\:#T@")!XOR370MBT,$]^$#1P2#T@`#QH/2`(E'!(OR +M3705BT,(]^$#1PB#T@`#QH/2`(E'"(ORB\9?7EM=PU535E>+?"04BUPD&(ML +M)!R+3"0@,_;![0)T18L#]^$#QH/2`(D'B_*+0P3WX0/&@](`B4<$B_*+0PCW +MX0/&@](`B4<(B_*+0PSWX0/&@](`B4<,B_*#PQ"#QQ!-=`+KNXML)!R#Y0-T +M,8L#]^$#QH/2`(D'B_)-="&+0P3WX0/&@](`B4<$B_)-=`^+0PCWX0/&@](` +MB4<(B_*+QE]>6UW#4U97BW0D$(M\)!2+7"08P>L"=#6+!_?@B0:)5@2+1P3W +MX(E&"(E6#(M'"/?@B480B584BT<,]^")1AB)5AR#QQ"#QB!+=`+KRXM<)!B# +MXP-T)8L']^")!HE6!$MT&8M'!/?@B48(B58,2W0+BT<(]^")1A")5A1?7EO# +MBU0D!(M$)`CW="0,PRYF:6QE`````````/[_``!G`BY<8W)Y<'1O7&)N7&%S +M;5QX.#9N=#,R+F%S;0```````````"YT97AT``````````$````#`?(!```` +M`````````````````"YD871A``````````(````#`0`````````````````` +M```````````$``````````$`(``"```````5````R0````$`(``"```````B +M````:@$```$`(``"```````P````Y0$```$`(``"`#H```!?8FY?;75L7V%D +L9%]W;W)D`%]B;E]M=6Q?=V]R9`!?8FY?<W%R7W=O<F1S`%]B;E]D:78V-``` +` +end diff --git a/crypto/bn/asm/x86w16.asm b/crypto/bn/asm/x86w16.asm new file mode 100644 index 0000000000..66874913e9 --- /dev/null +++ b/crypto/bn/asm/x86w16.asm @@ -0,0 +1,297 @@ +; Static Name Aliases +; + TITLE bn_mulw.c + .8087 +F_TEXT SEGMENT WORD PUBLIC 'CODE' +F_TEXT ENDS +_DATA SEGMENT WORD PUBLIC 'DATA' +_DATA ENDS +CONST SEGMENT WORD PUBLIC 'CONST' +CONST ENDS +_BSS SEGMENT WORD PUBLIC 'BSS' +_BSS ENDS +DGROUP GROUP CONST, _BSS, _DATA + ASSUME DS: DGROUP, SS: DGROUP +F_TEXT SEGMENT + ASSUME CS: F_TEXT + PUBLIC _bn_mul_add_word +_bn_mul_add_word PROC FAR +; Line 58 + push bp + push bx + push si + push di + push ds + push es + mov bp,sp +; w = 26 +; num = 24 +; ap = 20 +; rp = 16 + xor si,si ;c=0; + mov di,WORD PTR [bp+16] ; load r + mov ds,WORD PTR [bp+18] ; load r + mov bx,WORD PTR [bp+20] ; load a + mov es,WORD PTR [bp+22] ; load a + mov cx,WORD PTR [bp+26] ; load w + mov bp,WORD PTR [bp+24] ; load num + + shr bp,1 ; div count by 4 and do groups of 4 + shr bp,1 + je $L555 + +$L546: + mov ax,cx + mul WORD PTR es:[bx] ; w* *a + add ax,WORD PTR ds:[di] ; + *r + adc dx,0 + adc ax,si + adc dx,0 + mov WORD PTR ds:[di],ax + mov si,dx + ; + mov ax,cx + mul WORD PTR es:[bx+2] ; w* *a + add ax,WORD PTR ds:[di+2] ; + *r + adc dx,0 + adc ax,si + adc dx,0 + mov WORD PTR ds:[di+2],ax + mov si,dx + ; + mov ax,cx + mul WORD PTR es:[bx+4] ; w* *a + add ax,WORD PTR ds:[di+4] ; + *r + adc dx,0 + adc ax,si + adc dx,0 + mov WORD PTR ds:[di+4],ax + mov si,dx + ; + mov ax,cx + mul WORD PTR es:[bx+6] ; w* *a + add ax,WORD PTR ds:[di+6] ; + *r + adc dx,0 + adc ax,si + adc dx,0 + mov WORD PTR ds:[di+6],ax + mov si,dx + ; + add bx,8 + add di,8 + ; + dec bp + je $L555 + jmp $L546 +; +; +$L555: + mov bp,sp + mov bp,WORD PTR [bp+24] ; load num + and bp,3 + dec bp + js $L547 + + mov ax,cx + mul WORD PTR es:[bx] ; w* *a + add ax,WORD PTR ds:[di] ; + *r + adc dx,0 + adc ax,si + adc dx,0 + mov WORD PTR ds:[di],ax + mov si,dx + dec bp + js $L547 ; Note that we are now testing for -1 + ; + mov ax,cx + mul WORD PTR es:[bx+2] ; w* *a + add ax,WORD PTR ds:[di+2] ; + *r + adc dx,0 + adc ax,si + adc dx,0 + mov WORD PTR ds:[di+2],ax + mov si,dx + dec bp + js $L547 + ; + mov ax,cx + mul WORD PTR es:[bx+4] ; w* *a + add ax,WORD PTR ds:[di+4] ; + *r + adc dx,0 + adc ax,si + adc dx,0 + mov WORD PTR ds:[di+4],ax + mov si,dx +$L547: + mov ax,si + pop es + pop ds + pop di + pop si + pop bx + pop bp + ret + nop + +_bn_mul_add_word ENDP + PUBLIC _bn_mul_word +_bn_mul_word PROC FAR +; Line 76 + push bp + push bx + push si + push di + push ds + push es + xor si,si + mov bp,sp + mov di,WORD PTR [bp+16] ; r + mov ds,WORD PTR [bp+18] + mov bx,WORD PTR [bp+20] ; a + mov es,WORD PTR [bp+22] + mov cx,WORD PTR [bp+26] ; w + mov bp,WORD PTR [bp+24] ; num +$FC743: + mov ax,cx + mul WORD PTR es:[bx] + add ax,si + adc dx,0 + mov WORD PTR ds:[di],ax + mov si,dx + dec bp + je $L764 + ; + mov ax,cx + mul WORD PTR es:[bx+2] + add ax,si + adc dx,0 + mov WORD PTR ds:[di+2],ax + mov si,dx + dec bp + je $L764 + ; + mov ax,cx + mul WORD PTR es:[bx+4] + add ax,si + adc dx,0 + mov WORD PTR ds:[di+4],ax + mov si,dx + dec bp + je $L764 + ; + mov ax,cx + mul WORD PTR es:[bx+6] + add ax,si + adc dx,0 + mov WORD PTR ds:[di+6],ax + mov si,dx + dec bp + je $L764 + ; + add bx,8 + add di,8 + jmp $FC743 + nop +$L764: + mov ax,si + pop es + pop ds + pop di + pop si + pop bx + pop bp + ret + nop +_bn_mul_word ENDP + PUBLIC _bn_sqr_words +_bn_sqr_words PROC FAR +; Line 92 + push bp + push bx + push si + push di + push ds + push es + mov bp,sp + mov si,WORD PTR [bp+16] + mov ds,WORD PTR [bp+18] + mov di,WORD PTR [bp+20] + mov es,WORD PTR [bp+22] + mov bx,WORD PTR [bp+24] + + mov bp,bx ; save a memory lookup later + shr bx,1 ; div count by 4 and do groups of 4 + shr bx,1 + je $L666 + +$L765: + mov ax,WORD PTR es:[di] + mul ax + mov WORD PTR ds:[si],ax + mov WORD PTR ds:[si+2],dx + ; + mov ax,WORD PTR es:[di+2] + mul ax + mov WORD PTR ds:[si+4],ax + mov WORD PTR ds:[si+6],dx + ; + mov ax,WORD PTR es:[di+4] + mul ax + mov WORD PTR ds:[si+8],ax + mov WORD PTR ds:[si+10],dx + ; + mov ax,WORD PTR es:[di+6] + mul ax + mov WORD PTR ds:[si+12],ax + mov WORD PTR ds:[si+14],dx + ; + add di,8 + add si,16 + dec bx + je $L666 + jmp $L765 +$L666: + and bp,3 + dec bp ; The copied value of bx (num) + js $L645 + ; + mov ax,WORD PTR es:[di] + mul ax + mov WORD PTR ds:[si],ax + mov WORD PTR ds:[si+2],dx + dec bp + js $L645 + ; + mov ax,WORD PTR es:[di+2] + mul ax + mov WORD PTR ds:[si+4],ax + mov WORD PTR ds:[si+6],dx + dec bp + js $L645 + ; + mov ax,WORD PTR es:[di+4] + mul ax + mov WORD PTR ds:[si+8],ax + mov WORD PTR ds:[si+10],dx +$L645: + pop es + pop ds + pop di + pop si + pop bx + pop bp + ret + +_bn_sqr_words ENDP + PUBLIC _bn_div64 +_bn_div64 PROC FAR + push bp + mov bp,sp + mov dx, WORD PTR [bp+6] + mov ax, WORD PTR [bp+8] + div WORD PTR [bp+10] + pop bp + ret +_bn_div64 ENDP +F_TEXT ENDS +END diff --git a/crypto/bn/asm/x86w16.uu b/crypto/bn/asm/x86w16.uu new file mode 100644 index 0000000000..89c5e144b7 --- /dev/null +++ b/crypto/bn/asm/x86w16.uu @@ -0,0 +1,20 @@ +begin 640 x86w16.obj +M@!P`&BY<8W)Y<'1O7&)N7&%S;5QX.#9W,38N87-MQY8U```$7T)34P5?1$%4 +M009$1U)/55`&1E]415A4!4-/3E-4`T)34P5#3TY35`1$051!!$-/1$5EF`<` +M2/`!!0H!&)@'`$@```,)`0R8!P!(```&"`$*F`<`2````@<!#YH(``3_`O\# +M_P14D$4```$-7V)N7W-Q<E]W;W)D<U4!``E?8FY?9&EV-C3B`0`07V)N7VUU +M;%]A9&1?=V]R9`````Q?8FY?;75L7W=O<F3<``#`B`0``*(!T:#T`0$``%53 +M5E<>!HOL,_:+?A".7A*+7A2.1A:+3AJ+;AC1[='M=&"+P2;W)P,%@](`$\:# +MT@")!8ORB\$F]V<"`T4"@](`$\:#T@")10*+\HO!)O=G!`-%!(/2`!/&@](` +MB44$B_*+P2;W9P8#10:#T@`3QH/2`(E%!HOR@\,(@\<(370"ZZ"+[(MN&(/E +M`TUX18O!)O<G`P6#T@`3QH/2`(D%B_)->"^+P2;W9P(#10*#T@`3QH/2`(E% +M`HOR37@6B\$F]V<$`T4$@](`$\:#T@")102+\HO&!Q]?7EM=RY!54U97'@8S +M]HOLBWX0CEX2BUX4CD86BTX:BVX8B\$F]R<#QH/2`(D%B_)-=$*+P2;W9P(# +MQH/2`(E%`HOR370OB\$F]V<$`\:#T@")102+\DUT'(O!)O=G!@/&@](`B44& +MB_)-=`F#PPB#QPCKKI"+Q@<?7UY;7<N055-65QX&B^R+=A".7A*+?A2.1A:+ +M7AB+Z]'KT>MT.2:+!??@B02)5`(FBT4"]^")1`2)5`8FBT4$]^")1`B)5`HF +MBT4&]^")1`R)5`Z#QPB#QA!+=`+KQX/E`TUX*":+!??@B02)5`)->!LFBT4" +M]^")1`2)5`9->`PFBT4$]^")1`B)5`H''U]>6UW+58OLBU8&BT8(]W8*7<NZ +%B@(``'0` +` +end diff --git a/crypto/bn/asm/x86w32.asm b/crypto/bn/asm/x86w32.asm new file mode 100644 index 0000000000..0e4452dfa9 --- /dev/null +++ b/crypto/bn/asm/x86w32.asm @@ -0,0 +1,303 @@ +; Static Name Aliases +; + TITLE bn_mulw.c + .386 +F_TEXT SEGMENT WORD USE16 PUBLIC 'CODE' +F_TEXT ENDS +_DATA SEGMENT WORD USE16 PUBLIC 'DATA' +_DATA ENDS +CONST SEGMENT WORD USE16 PUBLIC 'CONST' +CONST ENDS +_BSS SEGMENT WORD USE16 PUBLIC 'BSS' +_BSS ENDS +DGROUP GROUP CONST, _BSS, _DATA + ASSUME DS: DGROUP, SS: DGROUP +F_TEXT SEGMENT + ASSUME CS: F_TEXT + PUBLIC _bn_mul_add_word +_bn_mul_add_word PROC FAR +; Line 58 + push bp + push bx + push esi + push di + push ds + push es + mov bp,sp +; w = 28 +; num = 26 +; ap = 22 +; rp = 18 + xor esi,esi ;c=0; + mov di,WORD PTR [bp+18] ; load r + mov ds,WORD PTR [bp+20] ; load r + mov bx,WORD PTR [bp+22] ; load a + mov es,WORD PTR [bp+24] ; load a + mov ecx,DWORD PTR [bp+28] ; load w + mov bp,WORD PTR [bp+26] ; load num + shr bp,1 ; div count by 4 and do groups of 4 + shr bp,1 + je $L555 + +$L546: + mov eax,ecx + mul DWORD PTR es:[bx] ; w* *a + add eax,DWORD PTR ds:[di] ; + *r + adc edx,0 + adc eax,esi + adc edx,0 + mov DWORD PTR ds:[di],eax + mov esi,edx + ; + mov eax,ecx + mul DWORD PTR es:[bx+4] ; w* *a + add eax,DWORD PTR ds:[di+4] ; + *r + adc edx,0 + adc eax,esi + adc edx,0 + mov DWORD PTR ds:[di+4],eax + mov esi,edx + ; + mov eax,ecx + mul DWORD PTR es:[bx+8] ; w* *a + add eax,DWORD PTR ds:[di+8] ; + *r + adc edx,0 + adc eax,esi + adc edx,0 + mov DWORD PTR ds:[di+8],eax + mov esi,edx + ; + mov eax,ecx + mul DWORD PTR es:[bx+12] ; w* *a + add eax,DWORD PTR ds:[di+12] ; + *r + adc edx,0 + adc eax,esi + adc edx,0 + mov DWORD PTR ds:[di+12],eax + mov esi,edx + ; + add bx,16 + add di,16 + ; + dec bp + je $L555 + jmp $L546 +; +; +$L555: + mov bp,sp + mov bp,WORD PTR [bp+26] ; load num + and bp,3 + dec bp + js $L547 + + mov eax,ecx + mul DWORD PTR es:[bx] ; w* *a + add eax,DWORD PTR ds:[di] ; + *r + adc edx,0 + adc eax,esi + adc edx,0 + mov DWORD PTR ds:[di],eax + mov esi,edx + dec bp + js $L547 ; Note that we are now testing for -1 + ; + mov eax,ecx + mul DWORD PTR es:[bx+4] ; w* *a + add eax,DWORD PTR ds:[di+4] ; + *r + adc edx,0 + adc eax,esi + adc edx,0 + mov DWORD PTR ds:[di+4],eax + mov esi,edx + dec bp + js $L547 + ; + mov eax,ecx + mul DWORD PTR es:[bx+8] ; w* *a + add eax,DWORD PTR ds:[di+8] ; + *r + adc edx,0 + adc eax,esi + adc edx,0 + mov DWORD PTR ds:[di+8],eax + mov esi,edx +$L547: + mov eax,esi + mov edx,esi + shr edx,16 + pop es + pop ds + pop di + pop esi + pop bx + pop bp + ret + nop + +_bn_mul_add_word ENDP + PUBLIC _bn_mul_word +_bn_mul_word PROC FAR +; Line 76 + push bp + push bx + push esi + push di + push ds + push es + xor esi,esi + mov bp,sp + mov di,WORD PTR [bp+18] ; r + mov ds,WORD PTR [bp+20] + mov bx,WORD PTR [bp+22] ; a + mov es,WORD PTR [bp+24] + mov ecx,DWORD PTR [bp+28] ; w + mov bp,WORD PTR [bp+26] ; num + +$FC743: + mov eax,ecx + mul DWORD PTR es:[bx] + add eax,esi + adc edx,0 + mov DWORD PTR ds:[di],eax + mov esi,edx + dec bp + je $L764 + ; + mov eax,ecx + mul DWORD PTR es:[bx+4] + add eax,esi + adc edx,0 + mov DWORD PTR ds:[di+4],eax + mov esi,edx + dec bp + je $L764 + ; + mov eax,ecx + mul DWORD PTR es:[bx+8] + add eax,esi + adc edx,0 + mov DWORD PTR ds:[di+8],eax + mov esi,edx + dec bp + je $L764 + ; + mov eax,ecx + mul DWORD PTR es:[bx+12] + add eax,esi + adc edx,0 + mov DWORD PTR ds:[di+12],eax + mov esi,edx + dec bp + je $L764 + ; + add bx,16 + add di,16 + jmp $FC743 + nop +$L764: + mov eax,esi + mov edx,esi + shr edx,16 + pop es + pop ds + pop di + pop esi + pop bx + pop bp + ret + nop +_bn_mul_word ENDP + PUBLIC _bn_sqr_words +_bn_sqr_words PROC FAR +; Line 92 + push bp + push bx + push si + push di + push ds + push es + mov bp,sp + mov si,WORD PTR [bp+16] + mov ds,WORD PTR [bp+18] + mov di,WORD PTR [bp+20] + mov es,WORD PTR [bp+22] + mov bx,WORD PTR [bp+24] + + mov bp,bx ; save a memory lookup later + shr bx,1 ; div count by 4 and do groups of 4 + shr bx,1 + je $L666 + +$L765: + mov eax,DWORD PTR es:[di] + mul eax + mov DWORD PTR ds:[si],eax + mov DWORD PTR ds:[si+4],edx + ; + mov eax,DWORD PTR es:[di+4] + mul eax + mov DWORD PTR ds:[si+8],eax + mov DWORD PTR ds:[si+12],edx + ; + mov eax,DWORD PTR es:[di+8] + mul eax + mov DWORD PTR ds:[si+16],eax + mov DWORD PTR ds:[si+20],edx + ; + mov eax,DWORD PTR es:[di+12] + mul eax + mov DWORD PTR ds:[si+24],eax + mov DWORD PTR ds:[si+28],edx + ; + add di,16 + add si,32 + dec bx + je $L666 + jmp $L765 +$L666: + and bp,3 + dec bp ; The copied value of bx (num) + js $L645 + ; + mov eax,DWORD PTR es:[di] + mul eax + mov DWORD PTR ds:[si],eax + mov DWORD PTR ds:[si+4],edx + dec bp + js $L645 + ; + mov eax,DWORD PTR es:[di+4] + mul eax + mov DWORD PTR ds:[si+8],eax + mov DWORD PTR ds:[si+12],edx + dec bp + js $L645 + ; + mov eax,DWORD PTR es:[di+8] + mul eax + mov DWORD PTR ds:[si+16],eax + mov DWORD PTR ds:[si+20],edx +$L645: + pop es + pop ds + pop di + pop si + pop bx + pop bp + ret + +_bn_sqr_words ENDP + PUBLIC _bn_div64 +_bn_div64 PROC FAR + push bp + mov bp,sp + mov edx, DWORD PTR [bp+6] + mov eax, DWORD PTR [bp+10] + div DWORD PTR [bp+14] + mov edx,eax + shr edx,16 + pop bp + ret +_bn_div64 ENDP +F_TEXT ENDS +END diff --git a/crypto/bn/asm/x86w32.uu b/crypto/bn/asm/x86w32.uu new file mode 100644 index 0000000000..edcd84e25e --- /dev/null +++ b/crypto/bn/asm/x86w32.uu @@ -0,0 +1,23 @@ +begin 640 x86w32.obj +M@!P`&BY<8W)Y<'1O7&)N7&%S;5QX.#9W,S(N87-MR98U```$7T)34P5?1$%4 +M009$1U)/55`&1E]415A4!4-/3E-4`T)34P5#3TY35`1$051!!$-/1$5EF`<` +M2(`"!0H!AY@'`$@```,)`0R8!P!(```&"`$*F`<`2````@<!#YH(``3_`O\# +M_P14D$4```$-7V)N7W-Q<E]W;W)D<[\!``E?8FY?9&EV-C1H`@`07V)N7VUU +M;%]A9&1?=V]R9`````Q?8FY?;75L7W=O<F0B`0"(B`0``*(!T:"$`@$``%53 +M9E97'@:+[&8S]HM^$HY>%(M>%HY&&&:+3AR+;AK1[='M#X2``&:+P68F]R=F +M`P5F@](`9A/&9H/2`&:)!6:+\F:+P68F]V<$9@-%!&:#T@!F$\9F@](`9HE% +M!&:+\F:+P68F]V<(9@-%"&:#T@!F$\9F@](`9HE%"&:+\F:+P68F]V<,9@-% +M#&:#T@!F$\9F@](`9HE%#&:+\H/#$(/'$$UT`NN`B^R+;AJ#Y0-->%UFB\%F +M)O<G9@,%9H/2`&83QF:#T@!FB05FB_)->#]FB\%F)O=G!&8#101F@](`9A/& +M9H/2`&:)101FB_)->!YFB\%F)O=G"&8#10AF@](`9A/&9H/2`&:)10AFB_)F +MB\9FB]9FP>H0!Q]?9EY;7<N055-F5E<>!F8S]HOLBWX2CEX4BUX6CD889HM. +M'(MN&F:+P68F]R=F`\9F@](`9HD%9HOR37149HO!9B;W9P1F`\9F@](`9HE% +M!&:+\DUT.V:+P68F]V<(9@/&9H/2`&:)10AFB_)-=")FB\%F)O=G#&8#QF:# +MT@!FB44,9HOR370)@\,0@\<0ZY:09HO&9HO69L'J$`<?7V9>6UW+D%535E<> +M!HOLBW80CEX2BWX4CD86BUX8B^O1Z]'K=$EF)HL%9O?@9HD$9HE4!&8FBT4$ +M9O?@9HE$"&:)5`QF)HM%"&;WX&:)1!!FB5049B:+10QF]^!FB4089HE4'(/' +M$(/&($MT`NNW@^4#37@T9B:+!6;WX&:)!&:)5`1->"-F)HM%!&;WX&:)1`AF +MB50,37@09B:+10AF]^!FB4009HE4%`<?7UY;7<M5B^QFBU8&9HM&"F;W=@YF +.B]!FP>H07<O`B@(``'0` +` +end diff --git a/crypto/bn/bn.err b/crypto/bn/bn.err new file mode 100644 index 0000000000..5fe4b6dbf6 --- /dev/null +++ b/crypto/bn/bn.err @@ -0,0 +1,20 @@ +/* Error codes for the BN functions. */ + +/* Function codes. */ +#define BN_F_BN_BL_CTX_INIT 100 +#define BN_F_BN_BL_CTX_NEW 101 +#define BN_F_BN_BN2ASCII 102 +#define BN_F_BN_CTX_NEW 103 +#define BN_F_BN_DIV 104 +#define BN_F_BN_EXPAND2 105 +#define BN_F_BN_MOD_EXP_MONT 106 +#define BN_F_BN_MOD_INVERSE 107 +#define BN_F_BN_MOD_MUL_RECIPROCAL 108 +#define BN_F_BN_NEW 109 +#define BN_F_BN_RAND 110 + +/* Reason codes. */ +#define BN_R_BAD_RECIPROCAL 100 +#define BN_R_CALLED_WITH_EVEN_MODULUS 101 +#define BN_R_DIV_BY_ZERO 102 +#define BN_R_NO_INVERSE 103 diff --git a/crypto/bn/bn.h b/crypto/bn/bn.h new file mode 100644 index 0000000000..9326f4df50 --- /dev/null +++ b/crypto/bn/bn.h @@ -0,0 +1,433 @@ +/* crypto/bn/bn.org */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + * + * Always modify bn.org since bn.h is automatically generated from + * it during SSLeay configuration. + * + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + */ + +#ifndef HEADER_BN_H +#define HEADER_BN_H + +#ifdef __cplusplus +extern "C" { +#endif + +#undef BN_LLONG + +#ifdef WIN32 +#define BN_LLONG /* This comment stops Configure mutilating things */ +#endif + +#define RECP_MUL_MOD +#define MONT_MUL_MOD + +/* This next option uses the C libraries (2 word)/(1 word) function. + * If it is not defined, I use my C version (which is slower). + * The reason for this flag is that when the particular C compiler + * library routine is used, and the library is linked with a different + * compiler, the library is missing. This mostly happens when the + * library is built with gcc and then linked using nornal cc. This would + * be a common occurance because gcc normally produces code that is + * 2 times faster than system compilers for the big number stuff. + * For machines with only one compiler (or shared libraries), this should + * be on. Again this in only really a problem on machines + * using "long long's", are 32bit, and are not using my assember code. */ +#if defined(MSDOS) || defined(WINDOWS) || defined(linux) +#define BN_DIV2W +#endif + +/* Only one for the following should be defined */ +/* The prime number generation stuff may not work when + * EIGHT_BIT but I don't care since I've only used this mode + * for debuging the bignum libraries */ +#undef SIXTY_FOUR_BIT_LONG +#undef SIXTY_FOUR_BIT +#define THIRTY_TWO_BIT +#undef SIXTEEN_BIT +#undef EIGHT_BIT + +/* assuming long is 64bit - this is the DEC Alpha + * unsigned long long is only 64 bits :-(, don't define + * BN_LLONG for the DEC Alpha */ +#ifdef SIXTY_FOUR_BIT_LONG +#define BN_ULLONG unsigned long long +#define BN_ULONG unsigned long +#define BN_LONG long +#define BN_BITS 128 +#define BN_BYTES 8 +#define BN_BITS2 64 +#define BN_BITS4 32 +#define BN_MASK2 (0xffffffffffffffffL) +#define BN_MASK2l (0xffffffffL) +#define BN_MASK2h (0xffffffff00000000L) +#define BN_MASK2h1 (0xffffffff80000000L) +#define BN_TBIT (0x8000000000000000L) +#endif + +#ifdef SIXTY_FOUR_BIT +#undef BN_LLONG +/* #define BN_ULLONG unsigned long long */ +#define BN_ULONG unsigned long long +#define BN_LONG long long +#define BN_BITS 128 +#define BN_BYTES 8 +#define BN_BITS2 64 +#define BN_BITS4 32 +#define BN_MASK2 (0xffffffffffffffffLL) +#define BN_MASK2l (0xffffffffL) +#define BN_MASK2h (0xffffffff00000000LL) +#define BN_MASK2h1 (0xffffffff80000000LL) +#define BN_TBIT (0x8000000000000000LL) +#endif + +#ifdef THIRTY_TWO_BIT +#ifdef WIN32 +#define BN_ULLONG unsigned _int64 +#else +#define BN_ULLONG unsigned long long +#endif +#define BN_ULONG unsigned long +#define BN_LONG long +#define BN_BITS 64 +#define BN_BYTES 4 +#define BN_BITS2 32 +#define BN_BITS4 16 +#define BN_MASK2 (0xffffffffL) +#define BN_MASK2l (0xffff) +#define BN_MASK2h1 (0xffff8000L) +#define BN_MASK2h (0xffff0000L) +#define BN_TBIT (0x80000000L) +#endif + +#ifdef SIXTEEN_BIT +#ifndef BN_DIV2W +#define BN_DIV2W +#endif +#define BN_ULLONG unsigned long +#define BN_ULONG unsigned short +#define BN_LONG short +#define BN_BITS 32 +#define BN_BYTES 2 +#define BN_BITS2 16 +#define BN_BITS4 8 +#define BN_MASK2 (0xffff) +#define BN_MASK2l (0xff) +#define BN_MASK2h1 (0xff80) +#define BN_MASK2h (0xff00) +#define BN_TBIT (0x8000) +#endif + +#ifdef EIGHT_BIT +#ifndef BN_DIV2W +#define BN_DIV2W +#endif +#define BN_ULLONG unsigned short +#define BN_ULONG unsigned char +#define BN_LONG char +#define BN_BITS 16 +#define BN_BYTES 1 +#define BN_BITS2 8 +#define BN_BITS4 4 +#define BN_MASK2 (0xff) +#define BN_MASK2l (0xf) +#define BN_MASK2h1 (0xf8) +#define BN_MASK2h (0xf0) +#define BN_TBIT (0x80) +#endif + +#define BN_DEFAULT_BITS 1280 + +#ifdef BIGNUM +#undef BIGNUM +#endif + +typedef struct bignum_st + { + BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit chunks. */ + int top; /* Index of last used d +1. */ + /* The next are internal book keeping for bn_expand. */ + int max; /* Size of the d array. */ + int neg; /* one if the number is negative */ + } BIGNUM; + +/* Used for temp variables */ +#define BN_CTX_NUM 12 +typedef struct bignum_ctx + { + int tos; + BIGNUM *bn[BN_CTX_NUM+1]; + } BN_CTX; + +/* Used for montgomery multiplication */ +typedef struct bn_mont_ctx_st + { + int ri; /* number of bits in R */ + BIGNUM *RR; /* used to convert to montgomery form */ + BIGNUM *N; /* The modulus */ + BIGNUM *Ni; /* The inverse of N */ + BN_ULONG n0; /* word form of inverse, normally only one of + * Ni or n0 is defined */ + } BN_MONT_CTX; + +#define BN_to_montgomery(r,a,mont,ctx) BN_mod_mul_montgomery(\ + r,a,(mont)->RR,(mont),ctx) + +#define BN_prime_checks (5) + +#define BN_num_bytes(a) ((BN_num_bits(a)+7)/8) +#define BN_is_word(a,w) (((a)->top == 1) && ((a)->d[0] == (BN_ULONG)(w))) +#define BN_is_zero(a) (((a)->top <= 1) && ((a)->d[0] == (BN_ULONG)0)) +#define BN_is_one(a) (BN_is_word((a),1)) +#define BN_is_odd(a) ((a)->d[0] & 1) +#define BN_one(a) (BN_set_word((a),1)) +#define BN_zero(a) (BN_set_word((a),0)) + +#define bn_fix_top(a) \ + { \ + BN_ULONG *fix_top_l; \ + for (fix_top_l= &((a)->d[(a)->top-1]); (a)->top > 0; (a)->top--) \ + if (*(fix_top_l--)) break; \ + } + +#define bn_expand(n,b) ((((b)/BN_BITS2) <= (n)->max)?(n):bn_expand2((n),(b))) + + +#ifndef NOPROTO +BIGNUM *BN_value_one(void); +char * BN_options(void); +BN_CTX *BN_CTX_new(void); +void BN_CTX_free(BN_CTX *c); +int BN_rand(BIGNUM *rnd, int bits, int top,int bottom); +int BN_num_bits(BIGNUM *a); +int BN_num_bits_word(BN_ULONG); +BIGNUM *BN_new(void); +void BN_clear_free(BIGNUM *a); +BIGNUM *BN_copy(BIGNUM *a, BIGNUM *b); +BIGNUM *BN_bin2bn(unsigned char *s,int len,BIGNUM *ret); +int BN_bn2bin(BIGNUM *a, unsigned char *to); +int BN_sub(BIGNUM *r, BIGNUM *a, BIGNUM *b); +void bn_qsub(BIGNUM *r, BIGNUM *a, BIGNUM *b); +void bn_qadd(BIGNUM *r, BIGNUM *a, BIGNUM *b); +int BN_add(BIGNUM *r, BIGNUM *a, BIGNUM *b); +int BN_mod(BIGNUM *rem, BIGNUM *m, BIGNUM *d, BN_CTX *ctx); +int BN_div(BIGNUM *dv, BIGNUM *rem, BIGNUM *m, BIGNUM *d, BN_CTX *ctx); +int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b); +int BN_sqr(BIGNUM *r, BIGNUM *a,BN_CTX *ctx); +BN_ULONG BN_mod_word(BIGNUM *a, unsigned long w); +BN_ULONG BN_div_word(BIGNUM *a, unsigned long w); +int BN_add_word(BIGNUM *a, unsigned long w); +int BN_set_word(BIGNUM *a, unsigned long w); +unsigned long BN_get_word(BIGNUM *a); +int BN_cmp(BIGNUM *a, BIGNUM *b); +void BN_free(BIGNUM *a); +int BN_is_bit_set(BIGNUM *a, int n); +int BN_lshift(BIGNUM *r, BIGNUM *a, int n); +int BN_lshift1(BIGNUM *r, BIGNUM *a); +int BN_mod_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m,BN_CTX *ctx); +int BN_mod_exp_mont(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m,BN_CTX *ctx); +int BN_mod_exp_recp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m,BN_CTX *ctx); +int BN_mod_exp_simple(BIGNUM *r, BIGNUM *a, BIGNUM *p, + BIGNUM *m,BN_CTX *ctx); +int BN_mask_bits(BIGNUM *a,int n); +int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *x, BIGNUM *y, BIGNUM *m, + BIGNUM *i, int nb, BN_CTX *ctx); +int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, BIGNUM *m, + BN_CTX *ctx); +#ifndef WIN16 +int BN_print_fp(FILE *fp, BIGNUM *a); +#endif +#ifdef HEADER_BIO_H +int BN_print(BIO *fp, BIGNUM *a); +#else +int BN_print(char *fp, BIGNUM *a); +#endif +int BN_reciprocal(BIGNUM *r, BIGNUM *m, BN_CTX *ctx); +int BN_rshift(BIGNUM *r, BIGNUM *a, int n); +int BN_rshift1(BIGNUM *r, BIGNUM *a); +void BN_clear(BIGNUM *a); +BIGNUM *bn_expand2(BIGNUM *b, int bits); +BIGNUM *BN_dup(BIGNUM *a); +int BN_ucmp(BIGNUM *a, BIGNUM *b); +int BN_set_bit(BIGNUM *a, int n); +int BN_clear_bit(BIGNUM *a, int n); +char * BN_bn2ascii(BIGNUM *a); +int BN_ascii2bn(BIGNUM **a,char *str); +int BN_gcd(BIGNUM *r,BIGNUM *in_a,BIGNUM *in_b,BN_CTX *ctx); +BIGNUM *BN_mod_inverse(BIGNUM *a, BIGNUM *n,BN_CTX *ctx); +BIGNUM *BN_generate_prime(int bits,int strong,BIGNUM *add, + BIGNUM *rem,void (*callback)(int,int)); +int BN_is_prime(BIGNUM *p,int nchecks,void (*callback)(int,int), + BN_CTX *ctx); +void ERR_load_BN_strings(void ); + +BN_ULONG bn_mul_add_word(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w); +BN_ULONG bn_mul_word(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w); +void bn_sqr_words(BN_ULONG *rp, BN_ULONG *ap, int num); +BN_ULONG bn_div64(BN_ULONG h, BN_ULONG l, BN_ULONG d); + +BN_MONT_CTX *BN_MONT_CTX_new(void ); +int BN_mod_mul_montgomery(BIGNUM *r,BIGNUM *a,BIGNUM *b,BN_MONT_CTX *mont, + BN_CTX *ctx); +int BN_from_montgomery(BIGNUM *r,BIGNUM *a,BN_MONT_CTX *mont,BN_CTX *ctx); +void BN_MONT_CTX_free(BN_MONT_CTX *mont); +int BN_MONT_CTX_set(BN_MONT_CTX *mont,BIGNUM *modulus,BN_CTX *ctx); + +#else + +BIGNUM *BN_value_one(); +char * BN_options(); +BN_CTX *BN_CTX_new(); +void BN_CTX_free(); +int BN_rand(); +int BN_num_bits(); +int BN_num_bits_word(); +BIGNUM *BN_new(); +void BN_clear_free(); +BIGNUM *BN_copy(); +BIGNUM *BN_bin2bn(); +int BN_bn2bin(); +int BN_sub(); +void bn_qsub(); +void bn_qadd(); +int BN_add(); +int BN_mod(); +int BN_div(); +int BN_mul(); +int BN_sqr(); +BN_ULONG BN_mod_word(); +BN_ULONG BN_div_word(); +int BN_add_word(); +int BN_set_word(); +unsigned long BN_get_word(); +int BN_cmp(); +void BN_free(); +int BN_is_bit_set(); +int BN_lshift(); +int BN_lshift1(); +int BN_mod_exp(); +int BN_mod_exp_mont(); +int BN_mod_exp_recp(); +int BN_mod_exp_simple(); +int BN_mask_bits(); +int BN_mod_mul_reciprocal(); +int BN_mod_mul(); +#ifndef WIN16 +int BN_print_fp(); +#endif +int BN_print(); +int BN_reciprocal(); +int BN_rshift(); +int BN_rshift1(); +void BN_clear(); +BIGNUM *bn_expand2(); +BIGNUM *BN_dup(); +int BN_ucmp(); +int BN_set_bit(); +int BN_clear_bit(); +char * BN_bn2ascii(); +int BN_ascii2bn(); +int BN_gcd(); +BIGNUM *BN_mod_inverse(); +BIGNUM *BN_generate_prime(); +int BN_is_prime(); +void ERR_load_BN_strings(); + +BN_ULONG bn_mul_add_word(); +BN_ULONG bn_mul_word(); +void bn_sqr_words(); +BN_ULONG bn_div64(); + +int BN_mod_mul_montgomery(); +int BN_from_montgomery(); +BN_MONT_CTX *BN_MONT_CTX_new(); +void BN_MONT_CTX_free(); +int BN_MONT_CTX_set(); + +#endif + +/* BEGIN ERROR CODES */ +/* Error codes for the BN functions. */ + +/* Function codes. */ +#define BN_F_BN_BL_CTX_INIT 100 +#define BN_F_BN_BL_CTX_NEW 101 +#define BN_F_BN_BN2ASCII 102 +#define BN_F_BN_CTX_NEW 103 +#define BN_F_BN_DIV 104 +#define BN_F_BN_EXPAND2 105 +#define BN_F_BN_MOD_EXP_MONT 106 +#define BN_F_BN_MOD_INVERSE 107 +#define BN_F_BN_MOD_MUL_RECIPROCAL 108 +#define BN_F_BN_NEW 109 +#define BN_F_BN_RAND 110 + +/* Reason codes. */ +#define BN_R_BAD_RECIPROCAL 100 +#define BN_R_CALLED_WITH_EVEN_MODULUS 101 +#define BN_R_DIV_BY_ZERO 102 +#define BN_R_NO_INVERSE 103 + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/crypto/bn/bn.org b/crypto/bn/bn.org new file mode 100644 index 0000000000..9326f4df50 --- /dev/null +++ b/crypto/bn/bn.org @@ -0,0 +1,433 @@ +/* crypto/bn/bn.org */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + * + * Always modify bn.org since bn.h is automatically generated from + * it during SSLeay configuration. + * + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + */ + +#ifndef HEADER_BN_H +#define HEADER_BN_H + +#ifdef __cplusplus +extern "C" { +#endif + +#undef BN_LLONG + +#ifdef WIN32 +#define BN_LLONG /* This comment stops Configure mutilating things */ +#endif + +#define RECP_MUL_MOD +#define MONT_MUL_MOD + +/* This next option uses the C libraries (2 word)/(1 word) function. + * If it is not defined, I use my C version (which is slower). + * The reason for this flag is that when the particular C compiler + * library routine is used, and the library is linked with a different + * compiler, the library is missing. This mostly happens when the + * library is built with gcc and then linked using nornal cc. This would + * be a common occurance because gcc normally produces code that is + * 2 times faster than system compilers for the big number stuff. + * For machines with only one compiler (or shared libraries), this should + * be on. Again this in only really a problem on machines + * using "long long's", are 32bit, and are not using my assember code. */ +#if defined(MSDOS) || defined(WINDOWS) || defined(linux) +#define BN_DIV2W +#endif + +/* Only one for the following should be defined */ +/* The prime number generation stuff may not work when + * EIGHT_BIT but I don't care since I've only used this mode + * for debuging the bignum libraries */ +#undef SIXTY_FOUR_BIT_LONG +#undef SIXTY_FOUR_BIT +#define THIRTY_TWO_BIT +#undef SIXTEEN_BIT +#undef EIGHT_BIT + +/* assuming long is 64bit - this is the DEC Alpha + * unsigned long long is only 64 bits :-(, don't define + * BN_LLONG for the DEC Alpha */ +#ifdef SIXTY_FOUR_BIT_LONG +#define BN_ULLONG unsigned long long +#define BN_ULONG unsigned long +#define BN_LONG long +#define BN_BITS 128 +#define BN_BYTES 8 +#define BN_BITS2 64 +#define BN_BITS4 32 +#define BN_MASK2 (0xffffffffffffffffL) +#define BN_MASK2l (0xffffffffL) +#define BN_MASK2h (0xffffffff00000000L) +#define BN_MASK2h1 (0xffffffff80000000L) +#define BN_TBIT (0x8000000000000000L) +#endif + +#ifdef SIXTY_FOUR_BIT +#undef BN_LLONG +/* #define BN_ULLONG unsigned long long */ +#define BN_ULONG unsigned long long +#define BN_LONG long long +#define BN_BITS 128 +#define BN_BYTES 8 +#define BN_BITS2 64 +#define BN_BITS4 32 +#define BN_MASK2 (0xffffffffffffffffLL) +#define BN_MASK2l (0xffffffffL) +#define BN_MASK2h (0xffffffff00000000LL) +#define BN_MASK2h1 (0xffffffff80000000LL) +#define BN_TBIT (0x8000000000000000LL) +#endif + +#ifdef THIRTY_TWO_BIT +#ifdef WIN32 +#define BN_ULLONG unsigned _int64 +#else +#define BN_ULLONG unsigned long long +#endif +#define BN_ULONG unsigned long +#define BN_LONG long +#define BN_BITS 64 +#define BN_BYTES 4 +#define BN_BITS2 32 +#define BN_BITS4 16 +#define BN_MASK2 (0xffffffffL) +#define BN_MASK2l (0xffff) +#define BN_MASK2h1 (0xffff8000L) +#define BN_MASK2h (0xffff0000L) +#define BN_TBIT (0x80000000L) +#endif + +#ifdef SIXTEEN_BIT +#ifndef BN_DIV2W +#define BN_DIV2W +#endif +#define BN_ULLONG unsigned long +#define BN_ULONG unsigned short +#define BN_LONG short +#define BN_BITS 32 +#define BN_BYTES 2 +#define BN_BITS2 16 +#define BN_BITS4 8 +#define BN_MASK2 (0xffff) +#define BN_MASK2l (0xff) +#define BN_MASK2h1 (0xff80) +#define BN_MASK2h (0xff00) +#define BN_TBIT (0x8000) +#endif + +#ifdef EIGHT_BIT +#ifndef BN_DIV2W +#define BN_DIV2W +#endif +#define BN_ULLONG unsigned short +#define BN_ULONG unsigned char +#define BN_LONG char +#define BN_BITS 16 +#define BN_BYTES 1 +#define BN_BITS2 8 +#define BN_BITS4 4 +#define BN_MASK2 (0xff) +#define BN_MASK2l (0xf) +#define BN_MASK2h1 (0xf8) +#define BN_MASK2h (0xf0) +#define BN_TBIT (0x80) +#endif + +#define BN_DEFAULT_BITS 1280 + +#ifdef BIGNUM +#undef BIGNUM +#endif + +typedef struct bignum_st + { + BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit chunks. */ + int top; /* Index of last used d +1. */ + /* The next are internal book keeping for bn_expand. */ + int max; /* Size of the d array. */ + int neg; /* one if the number is negative */ + } BIGNUM; + +/* Used for temp variables */ +#define BN_CTX_NUM 12 +typedef struct bignum_ctx + { + int tos; + BIGNUM *bn[BN_CTX_NUM+1]; + } BN_CTX; + +/* Used for montgomery multiplication */ +typedef struct bn_mont_ctx_st + { + int ri; /* number of bits in R */ + BIGNUM *RR; /* used to convert to montgomery form */ + BIGNUM *N; /* The modulus */ + BIGNUM *Ni; /* The inverse of N */ + BN_ULONG n0; /* word form of inverse, normally only one of + * Ni or n0 is defined */ + } BN_MONT_CTX; + +#define BN_to_montgomery(r,a,mont,ctx) BN_mod_mul_montgomery(\ + r,a,(mont)->RR,(mont),ctx) + +#define BN_prime_checks (5) + +#define BN_num_bytes(a) ((BN_num_bits(a)+7)/8) +#define BN_is_word(a,w) (((a)->top == 1) && ((a)->d[0] == (BN_ULONG)(w))) +#define BN_is_zero(a) (((a)->top <= 1) && ((a)->d[0] == (BN_ULONG)0)) +#define BN_is_one(a) (BN_is_word((a),1)) +#define BN_is_odd(a) ((a)->d[0] & 1) +#define BN_one(a) (BN_set_word((a),1)) +#define BN_zero(a) (BN_set_word((a),0)) + +#define bn_fix_top(a) \ + { \ + BN_ULONG *fix_top_l; \ + for (fix_top_l= &((a)->d[(a)->top-1]); (a)->top > 0; (a)->top--) \ + if (*(fix_top_l--)) break; \ + } + +#define bn_expand(n,b) ((((b)/BN_BITS2) <= (n)->max)?(n):bn_expand2((n),(b))) + + +#ifndef NOPROTO +BIGNUM *BN_value_one(void); +char * BN_options(void); +BN_CTX *BN_CTX_new(void); +void BN_CTX_free(BN_CTX *c); +int BN_rand(BIGNUM *rnd, int bits, int top,int bottom); +int BN_num_bits(BIGNUM *a); +int BN_num_bits_word(BN_ULONG); +BIGNUM *BN_new(void); +void BN_clear_free(BIGNUM *a); +BIGNUM *BN_copy(BIGNUM *a, BIGNUM *b); +BIGNUM *BN_bin2bn(unsigned char *s,int len,BIGNUM *ret); +int BN_bn2bin(BIGNUM *a, unsigned char *to); +int BN_sub(BIGNUM *r, BIGNUM *a, BIGNUM *b); +void bn_qsub(BIGNUM *r, BIGNUM *a, BIGNUM *b); +void bn_qadd(BIGNUM *r, BIGNUM *a, BIGNUM *b); +int BN_add(BIGNUM *r, BIGNUM *a, BIGNUM *b); +int BN_mod(BIGNUM *rem, BIGNUM *m, BIGNUM *d, BN_CTX *ctx); +int BN_div(BIGNUM *dv, BIGNUM *rem, BIGNUM *m, BIGNUM *d, BN_CTX *ctx); +int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b); +int BN_sqr(BIGNUM *r, BIGNUM *a,BN_CTX *ctx); +BN_ULONG BN_mod_word(BIGNUM *a, unsigned long w); +BN_ULONG BN_div_word(BIGNUM *a, unsigned long w); +int BN_add_word(BIGNUM *a, unsigned long w); +int BN_set_word(BIGNUM *a, unsigned long w); +unsigned long BN_get_word(BIGNUM *a); +int BN_cmp(BIGNUM *a, BIGNUM *b); +void BN_free(BIGNUM *a); +int BN_is_bit_set(BIGNUM *a, int n); +int BN_lshift(BIGNUM *r, BIGNUM *a, int n); +int BN_lshift1(BIGNUM *r, BIGNUM *a); +int BN_mod_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m,BN_CTX *ctx); +int BN_mod_exp_mont(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m,BN_CTX *ctx); +int BN_mod_exp_recp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m,BN_CTX *ctx); +int BN_mod_exp_simple(BIGNUM *r, BIGNUM *a, BIGNUM *p, + BIGNUM *m,BN_CTX *ctx); +int BN_mask_bits(BIGNUM *a,int n); +int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *x, BIGNUM *y, BIGNUM *m, + BIGNUM *i, int nb, BN_CTX *ctx); +int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, BIGNUM *m, + BN_CTX *ctx); +#ifndef WIN16 +int BN_print_fp(FILE *fp, BIGNUM *a); +#endif +#ifdef HEADER_BIO_H +int BN_print(BIO *fp, BIGNUM *a); +#else +int BN_print(char *fp, BIGNUM *a); +#endif +int BN_reciprocal(BIGNUM *r, BIGNUM *m, BN_CTX *ctx); +int BN_rshift(BIGNUM *r, BIGNUM *a, int n); +int BN_rshift1(BIGNUM *r, BIGNUM *a); +void BN_clear(BIGNUM *a); +BIGNUM *bn_expand2(BIGNUM *b, int bits); +BIGNUM *BN_dup(BIGNUM *a); +int BN_ucmp(BIGNUM *a, BIGNUM *b); +int BN_set_bit(BIGNUM *a, int n); +int BN_clear_bit(BIGNUM *a, int n); +char * BN_bn2ascii(BIGNUM *a); +int BN_ascii2bn(BIGNUM **a,char *str); +int BN_gcd(BIGNUM *r,BIGNUM *in_a,BIGNUM *in_b,BN_CTX *ctx); +BIGNUM *BN_mod_inverse(BIGNUM *a, BIGNUM *n,BN_CTX *ctx); +BIGNUM *BN_generate_prime(int bits,int strong,BIGNUM *add, + BIGNUM *rem,void (*callback)(int,int)); +int BN_is_prime(BIGNUM *p,int nchecks,void (*callback)(int,int), + BN_CTX *ctx); +void ERR_load_BN_strings(void ); + +BN_ULONG bn_mul_add_word(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w); +BN_ULONG bn_mul_word(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w); +void bn_sqr_words(BN_ULONG *rp, BN_ULONG *ap, int num); +BN_ULONG bn_div64(BN_ULONG h, BN_ULONG l, BN_ULONG d); + +BN_MONT_CTX *BN_MONT_CTX_new(void ); +int BN_mod_mul_montgomery(BIGNUM *r,BIGNUM *a,BIGNUM *b,BN_MONT_CTX *mont, + BN_CTX *ctx); +int BN_from_montgomery(BIGNUM *r,BIGNUM *a,BN_MONT_CTX *mont,BN_CTX *ctx); +void BN_MONT_CTX_free(BN_MONT_CTX *mont); +int BN_MONT_CTX_set(BN_MONT_CTX *mont,BIGNUM *modulus,BN_CTX *ctx); + +#else + +BIGNUM *BN_value_one(); +char * BN_options(); +BN_CTX *BN_CTX_new(); +void BN_CTX_free(); +int BN_rand(); +int BN_num_bits(); +int BN_num_bits_word(); +BIGNUM *BN_new(); +void BN_clear_free(); +BIGNUM *BN_copy(); +BIGNUM *BN_bin2bn(); +int BN_bn2bin(); +int BN_sub(); +void bn_qsub(); +void bn_qadd(); +int BN_add(); +int BN_mod(); +int BN_div(); +int BN_mul(); +int BN_sqr(); +BN_ULONG BN_mod_word(); +BN_ULONG BN_div_word(); +int BN_add_word(); +int BN_set_word(); +unsigned long BN_get_word(); +int BN_cmp(); +void BN_free(); +int BN_is_bit_set(); +int BN_lshift(); +int BN_lshift1(); +int BN_mod_exp(); +int BN_mod_exp_mont(); +int BN_mod_exp_recp(); +int BN_mod_exp_simple(); +int BN_mask_bits(); +int BN_mod_mul_reciprocal(); +int BN_mod_mul(); +#ifndef WIN16 +int BN_print_fp(); +#endif +int BN_print(); +int BN_reciprocal(); +int BN_rshift(); +int BN_rshift1(); +void BN_clear(); +BIGNUM *bn_expand2(); +BIGNUM *BN_dup(); +int BN_ucmp(); +int BN_set_bit(); +int BN_clear_bit(); +char * BN_bn2ascii(); +int BN_ascii2bn(); +int BN_gcd(); +BIGNUM *BN_mod_inverse(); +BIGNUM *BN_generate_prime(); +int BN_is_prime(); +void ERR_load_BN_strings(); + +BN_ULONG bn_mul_add_word(); +BN_ULONG bn_mul_word(); +void bn_sqr_words(); +BN_ULONG bn_div64(); + +int BN_mod_mul_montgomery(); +int BN_from_montgomery(); +BN_MONT_CTX *BN_MONT_CTX_new(); +void BN_MONT_CTX_free(); +int BN_MONT_CTX_set(); + +#endif + +/* BEGIN ERROR CODES */ +/* Error codes for the BN functions. */ + +/* Function codes. */ +#define BN_F_BN_BL_CTX_INIT 100 +#define BN_F_BN_BL_CTX_NEW 101 +#define BN_F_BN_BN2ASCII 102 +#define BN_F_BN_CTX_NEW 103 +#define BN_F_BN_DIV 104 +#define BN_F_BN_EXPAND2 105 +#define BN_F_BN_MOD_EXP_MONT 106 +#define BN_F_BN_MOD_INVERSE 107 +#define BN_F_BN_MOD_MUL_RECIPROCAL 108 +#define BN_F_BN_NEW 109 +#define BN_F_BN_RAND 110 + +/* Reason codes. */ +#define BN_R_BAD_RECIPROCAL 100 +#define BN_R_CALLED_WITH_EVEN_MODULUS 101 +#define BN_R_DIV_BY_ZERO 102 +#define BN_R_NO_INVERSE 103 + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/crypto/bn/bn_add.c b/crypto/bn/bn_add.c new file mode 100644 index 0000000000..ecdb7453b5 --- /dev/null +++ b/crypto/bn/bn_add.c @@ -0,0 +1,170 @@ +/* crypto/bn/bn_add.c */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include "cryptlib.h" +#include "bn_lcl.h" + +/* r can == a or b */ +int BN_add(r, a, b) +BIGNUM *r; +BIGNUM *a; +BIGNUM *b; + { + int i; + BIGNUM *tmp; + + /* a + b a+b + * a + -b a-b + * -a + b b-a + * -a + -b -(a+b) + */ + if (a->neg ^ b->neg) + { + /* only one is negative */ + if (a->neg) + { tmp=a; a=b; b=tmp; } + + /* we are now a - b */ + if (bn_expand(r,((a->top > b->top)?a->top:b->top)*BN_BITS2) + == NULL) return(0); + + if (BN_ucmp(a,b) < 0) + { + bn_qsub(r,b,a); + r->neg=1; + } + else + { + bn_qsub(r,a,b); + r->neg=0; + } + return(1); + } + + if (a->neg) /* both are neg */ + r->neg=1; + else + r->neg=0; + + i=(a->top > b->top); + if (bn_expand(r,(((i)?a->top:b->top)+1)*BN_BITS2) == NULL) return(0); + + if (i) + bn_qadd(r,a,b); + else + bn_qadd(r,b,a); + return(1); + } + +/* unsigned add of b to a, r must be large enough */ +void bn_qadd(r,a,b) +BIGNUM *r; +BIGNUM *a; +BIGNUM *b; + { + register int i; + int max,min; + BN_ULONG *ap,*bp,*rp,carry,t1,t2; + + max=a->top; + min=b->top; + r->top=max; + + ap=a->d; + bp=b->d; + rp=r->d; + carry=0; + for (i=0; i<min; i++) + { + t1= *(ap++); + t2= *(bp++); + if (carry) + { + carry=(t2 >= ((~t1)&BN_MASK2)); + t2=(t1+t2+1)&BN_MASK2; + } + else + { + t2=(t1+t2)&BN_MASK2; + carry=(t2 < t1); + } + *(rp++)=t2; + } + if (carry) + { + while (i < max) + { + t1= *(ap++); + t2=(t1+1)&BN_MASK2; + *(rp++)=t2; + carry=(t2 < t1); + i++; + if (!carry) break; + } + if ((i >= max) && carry) + { + *(rp++)=1; + r->top++; + } + } + for (; i<max; i++) + *(rp++)= *(ap++); + /* memcpy(rp,ap,sizeof(*ap)*(max-i));*/ + } + diff --git a/crypto/bn/bn_bld.c b/crypto/bn/bn_bld.c new file mode 100644 index 0000000000..966db43962 --- /dev/null +++ b/crypto/bn/bn_bld.c @@ -0,0 +1,144 @@ +/* crypto/bn/bn_bld.c */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include "cryptlib.h" +#include "bn_lcl.h" + +BN_BL_CTX *BN_BL_CTX_new() + { + BN_BL_CTX *ret; + + if ((ret=(BN_BL_CTX *)Malloc(sizeof(BN_BL_CTX))) == NULL) + { + BNerr(BN_F_BN_BL_CTX_NEW,ERR_R_MALLOC_FAILURE); + return(NULL); + } + if ((ret->num=BN_new()) == NULL) goto err; + if ((ret->mod=BN_new()) == NULL) goto err; + ret->inum=NULL; + ret->count=16; + ret->count=1; + return(ret); + } + +int BN_BL_CTX_Init(a,mod) +BN_BL_CTX *a; +BIGNUM *mod; + { + int i; + BN_CTX *ctx; + + if ((ctx=BN_CTX_new()) == NULL) goto m_err; + + if (BN_copy(a->mod,mod) == NULL) goto err; + i=BN_num_bits(mod); + if (!BN_rand(a->num,i,1,0)) goto err; + + if (a->inum != NULL) BN_clear_free(a->inum); + a->inum=BN_mod_inverse(a->num,a->mod,ctx) + ret->count=16; + return(1); +m_err: + BNerr(BN_F_BN_BL_CTX_INIT,ERR_R_MALLOC_FAILURE); +err: + return(0); + } + +BN_BL_CTX *BN_BL_CTX_Update(a) +BN_BL_CTX *a; + { + BN_CTX *ctx; + BN_BL_CTX *new; + + if (--a->count > 0) + return(1); + + new=BN_BL_CTX_new(); + /* set/get lock */ + if ((ctx=BN_CTX_new()) == NULL) + return(NULL); + new->inum=BN_new(); + + BN_mod_mul(new->num,a->num,a->num,a->mod,ctx); + BN_mod_mul(new->inum,a->inum,a->inum,a->mod,ctx); + BN_copy(new->mod,a->mod); + BN_BL_CTX_free(a); + return(new); + } + +void BN_BL_CTX_free(a) +BN_BL_CTX *a; + { + int i; + + if (a == NULL) return; + + i=CRYPTO_add(&a->references,-1,CRYPTO_LOCK_RSA); + if (i > 0) return; +#ifdef REF_CHECK + if (i < 0) + { + fprintf(stderr,"BN_BL_CTX_free, bad reference count\n"); + abort(); + } +#endif + if (a->num == NULL) BN_clear_free(a->num); + if (a->inum == NULL) BN_clear_free(a->inum); + if (a->mod == NULL) BN_clear_free(a->mod); + } diff --git a/crypto/bn/bn_div.c b/crypto/bn/bn_div.c new file mode 100644 index 0000000000..0ce4d4182f --- /dev/null +++ b/crypto/bn/bn_div.c @@ -0,0 +1,286 @@ +/* crypto/bn/bn_div.c */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include "cryptlib.h" +#include "bn_lcl.h" + +/* The old slow way */ +#if 0 +int BN_div(dv, rem, m, d,ctx) +BIGNUM *dv; +BIGNUM *rem; +BIGNUM *m; +BIGNUM *d; +BN_CTX *ctx; + { + int i,nm,nd; + BIGNUM *D; + + if (BN_is_zero(d)) + { + BNerr(BN_F_BN_DIV,BN_R_DIV_BY_ZERO); + return(0); + } + + if (BN_ucmp(m,d) < 0) + { + if (rem != NULL) + { if (BN_copy(rem,m) == NULL) return(0); } + if (dv != NULL) BN_zero(dv); + return(1); + } + + D=ctx->bn[ctx->tos]; + if (dv == NULL) dv=ctx->bn[ctx->tos+1]; + if (rem == NULL) rem=ctx->bn[ctx->tos+2]; + + nd=BN_num_bits(d); + nm=BN_num_bits(m); + if (BN_copy(D,d) == NULL) return(0); + if (BN_copy(rem,m) == NULL) return(0); + + /* The next 2 are needed so we can do a dv->d[0]|=1 later + * since BN_lshift1 will only work once there is a value :-) */ + BN_zero(dv); + dv->top=1; + + if (!BN_lshift(D,D,nm-nd)) return(0); + for (i=nm-nd; i>=0; i--) + { + if (!BN_lshift1(dv,dv)) return(0); + if (BN_ucmp(rem,D) >= 0) + { + dv->d[0]|=1; + bn_qsub(rem,rem,D); + } +/* CAN IMPROVE (and have now :=) */ + if (!BN_rshift1(D,D)) return(0); + } + rem->neg=BN_is_zero(rem)?0:m->neg; + dv->neg=m->neg^d->neg; + return(1); + } + +#else + +int BN_div(dv, rm, num, divisor,ctx) +BIGNUM *dv; +BIGNUM *rm; +BIGNUM *num; +BIGNUM *divisor; +BN_CTX *ctx; + { + int norm_shift,i,j,loop; + BIGNUM *tmp,wnum,*snum,*sdiv,*res; + BN_ULONG *resp,*wnump; + BN_ULONG d0,d1; + int num_n,div_n; + + if (BN_is_zero(num)) + { + BNerr(BN_F_BN_DIV,BN_R_DIV_BY_ZERO); + return(0); + } + + if (BN_ucmp(num,divisor) < 0) + { + if (rm != NULL) + { if (BN_copy(rm,num) == NULL) return(0); } + if (dv != NULL) BN_zero(dv); + return(1); + } + + tmp=ctx->bn[ctx->tos]; + tmp->neg=0; + snum=ctx->bn[ctx->tos+1]; + sdiv=ctx->bn[ctx->tos+2]; + if (dv == NULL) + res=ctx->bn[ctx->tos+3]; + else res=dv; + + /* First we normalise the numbers */ + norm_shift=BN_BITS2-((BN_num_bits(divisor))%BN_BITS2); + BN_lshift(sdiv,divisor,norm_shift); + sdiv->neg=0; + norm_shift+=BN_BITS2; + BN_lshift(snum,num,norm_shift); + snum->neg=0; + div_n=sdiv->top; + num_n=snum->top; + loop=num_n-div_n; + + /* Lets setup a 'window' into snum + * This is the part that corresponds to the current + * 'area' being divided */ + wnum.d= &(snum->d[loop]); + wnum.top= div_n; + wnum.max= snum->max; /* a bit of a lie */ + wnum.neg= 0; + + /* Get the top 2 words of sdiv */ + /* i=sdiv->top; */ + d0=sdiv->d[div_n-1]; + d1=(div_n == 1)?0:sdiv->d[div_n-2]; + + /* pointer to the 'top' of snum */ + wnump= &(snum->d[num_n-1]); + + /* Setup to 'res' */ + res->neg= (num->neg^divisor->neg); + res->top=loop; + if (!bn_expand(res,(loop+1)*BN_BITS2)) goto err; + resp= &(res->d[loop-1]); + + /* space for temp */ + if (!bn_expand(tmp,(div_n+1)*BN_BITS2)) goto err; + + if (BN_ucmp(&wnum,sdiv) >= 0) + { + bn_qsub(&wnum,&wnum,sdiv); + *resp=1; + res->d[res->top-1]=1; + } + else + res->top--; + resp--; + + for (i=0; i<loop-1; i++) + { + BN_ULONG q,n0,n1; + BN_ULONG l0; + + wnum.d--; wnum.top++; + n0=wnump[0]; + n1=wnump[-1]; + if (n0 == d0) + q=BN_MASK2; + else + q=bn_div64(n0,n1,d0); + { +#ifdef BN_LLONG + BN_ULLONG t1,t2,rem; + t1=((BN_ULLONG)n0<<BN_BITS2)|n1; + for (;;) + { + t2=(BN_ULLONG)d1*q; + rem=t1-(BN_ULLONG)q*d0; + if ((rem>>BN_BITS2) || + (t2 <= ((BN_ULLONG)(rem<<BN_BITS2)+wnump[-2]))) + break; + q--; + } +#else + BN_ULONG t1l,t1h,t2l,t2h,t3l,t3h,ql,qh,t3t; + t1h=n0; + t1l=n1; + for (;;) + { + t2l=LBITS(d1); t2h=HBITS(d1); + ql =LBITS(q); qh =HBITS(q); + mul64(t2l,t2h,ql,qh); /* t2=(BN_ULLONG)d1*q; */ + + t3t=LBITS(d0); t3h=HBITS(d0); + mul64(t3t,t3h,ql,qh); /* t3=t1-(BN_ULLONG)q*d0; */ + t3l=(t1l-t3t); + if (t3l > t1l) t3h++; + t3h=(t1h-t3h); + + /*if ((t3>>BN_BITS2) || + (t2 <= ((t3<<BN_BITS2)+wnump[-2]))) + break; */ + if (t3h) break; + if (t2h < t3l) break; + if ((t2h == t3l) && (t2l <= wnump[-2])) break; + + q--; + } +#endif + } + l0=bn_mul_word(tmp->d,sdiv->d,div_n,q); + tmp->d[div_n]=l0; + for (j=div_n+1; j>0; j--) + if (tmp->d[j-1]) break; + tmp->top=j; + + j=wnum.top; + BN_sub(&wnum,&wnum,tmp); + + snum->top=snum->top+wnum.top-j; + + if (wnum.neg) + { + q--; + j=wnum.top; + BN_add(&wnum,&wnum,sdiv); + snum->top+=wnum.top-j; + } + *(resp--)=q; + wnump--; + } + if (rm != NULL) + { + BN_rshift(rm,snum,norm_shift); + rm->neg=num->neg; + } + return(1); +err: + return(0); + } + +#endif diff --git a/crypto/bn/bn_err.c b/crypto/bn/bn_err.c new file mode 100644 index 0000000000..38818d6e67 --- /dev/null +++ b/crypto/bn/bn_err.c @@ -0,0 +1,98 @@ +/* lib/bn/bn_err.c */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +#include <stdio.h> +#include "err.h" +#include "bn.h" + +/* BEGIN ERROR CODES */ +static ERR_STRING_DATA BN_str_functs[]= + { +{ERR_PACK(0,BN_F_BN_BL_CTX_INIT,0), "BN_BL_CTX_INIT"}, +{ERR_PACK(0,BN_F_BN_BL_CTX_NEW,0), "BN_BL_CTX_NEW"}, +{ERR_PACK(0,BN_F_BN_BN2ASCII,0), "BN_bn2ascii"}, +{ERR_PACK(0,BN_F_BN_CTX_NEW,0), "BN_CTX_new"}, +{ERR_PACK(0,BN_F_BN_DIV,0), "BN_div"}, +{ERR_PACK(0,BN_F_BN_EXPAND2,0), "bn_expand2"}, +{ERR_PACK(0,BN_F_BN_MOD_EXP_MONT,0), "BN_mod_exp_mont"}, +{ERR_PACK(0,BN_F_BN_MOD_INVERSE,0), "BN_mod_inverse"}, +{ERR_PACK(0,BN_F_BN_MOD_MUL_RECIPROCAL,0), "BN_mod_mul_reciprocal"}, +{ERR_PACK(0,BN_F_BN_NEW,0), "BN_new"}, +{ERR_PACK(0,BN_F_BN_RAND,0), "BN_rand"}, +{0,NULL}, + }; + +static ERR_STRING_DATA BN_str_reasons[]= + { +{BN_R_BAD_RECIPROCAL ,"bad reciprocal"}, +{BN_R_CALLED_WITH_EVEN_MODULUS ,"called with even modulus"}, +{BN_R_DIV_BY_ZERO ,"div by zero"}, +{BN_R_NO_INVERSE ,"no inverse"}, +{0,NULL}, + }; + +void ERR_load_BN_strings() + { + static int init=1; + + if (init) + { + init=0; + ERR_load_strings(ERR_LIB_BN,BN_str_functs); + ERR_load_strings(ERR_LIB_BN,BN_str_reasons); + } + } diff --git a/crypto/bn/bn_exp.c b/crypto/bn/bn_exp.c new file mode 100644 index 0000000000..0a0db370c3 --- /dev/null +++ b/crypto/bn/bn_exp.c @@ -0,0 +1,510 @@ +/* crypto/bn/bn_exp.c */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include "cryptlib.h" +#include "bn_lcl.h" + +/* slow but works */ +int BN_mod_mul(ret, a, b, m, ctx) +BIGNUM *ret; +BIGNUM *a; +BIGNUM *b; +BIGNUM *m; +BN_CTX *ctx; + { + BIGNUM *t; + int r=0; + + t=ctx->bn[ctx->tos++]; + if (a == b) + { if (!BN_sqr(t,a,ctx)) goto err; } + else + { if (!BN_mul(t,a,b)) goto err; } + if (!BN_mod(ret,t,m,ctx)) goto err; + r=1; +err: + ctx->tos--; + return(r); + } + +#if 0 +/* this one works - simple but works */ +int BN_mod_exp(r,a,p,m,ctx) +BIGNUM *r,*a,*p,*m; +BN_CTX *ctx; + { + int i,bits,ret=0; + BIGNUM *v,*tmp; + + v=ctx->bn[ctx->tos++]; + tmp=ctx->bn[ctx->tos++]; + + if (BN_copy(v,a) == NULL) goto err; + bits=BN_num_bits(p); + + if (BN_is_odd(p)) + { if (BN_copy(r,a) == NULL) goto err; } + else { if (BN_one(r)) goto err; } + + for (i=1; i<bits; i++) + { + if (!BN_sqr(tmp,v,ctx)) goto err; + if (!BN_mod(v,tmp,m,ctx)) goto err; + if (BN_is_bit_set(p,i)) + { + if (!BN_mul(tmp,r,v)) goto err; + if (!BN_mod(r,tmp,m,ctx)) goto err; + } + } + ret=1; +err: + ctx->tos-=2; + return(ret); + } + +#endif + +int BN_mod_exp(r,a,p,m,ctx) +BIGNUM *r; +BIGNUM *a; +BIGNUM *p; +BIGNUM *m; +BN_CTX *ctx; + { + int ret; + +#ifdef MONT_MUL_MOD + /* I have finally been able to take out this pre-condition of + * the top bit being set. It was caused by an error in BN_div + * with negatives. There was also another problem when for a^b%m + * a >= m. eay 07-May-97 */ +/* if ((m->d[m->top-1]&BN_TBIT) && BN_is_odd(m)) */ + + if (BN_is_odd(m)) + { ret=BN_mod_exp_mont(r,a,p,m,ctx); } + else +#endif +#ifdef RECP_MUL_MOD + { ret=BN_mod_exp_recp(r,a,p,m,ctx); } +#else + { ret=BN_mod_exp_simple(r,a,p,m,ctx); } +#endif + + return(ret); + } + +/* #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 nb,i,j,bits,ret=0,wstart,wend,window,wvalue; + int start=1; + BIGNUM *d,*aa; + BIGNUM *val[16]; + + d=ctx->bn[ctx->tos++]; + aa=ctx->bn[ctx->tos++]; + bits=BN_num_bits(p); + + if (bits == 0) + { + BN_one(r); + return(1); + } + nb=BN_reciprocal(d,m,ctx); + if (nb == -1) goto err; + + val[0]=BN_new(); + if (!BN_mod(val[0],a,m,ctx)) goto err; /* 1 */ + if (!BN_mod_mul_reciprocal(aa,val[0],val[0],m,d,nb,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++) + { + val[i]=BN_new(); + if (!BN_mod_mul_reciprocal(val[i],val[i-1],aa,m,d,nb,ctx)) + goto err; + } + for (; i<16; i++) + val[i]=NULL; + + 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,m,d,nb,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,m,d,nb,ctx)) + goto err; + } + + /* wvalue will be an odd number < 2^window */ + if (!BN_mod_mul_reciprocal(r,r,val[wvalue>>1],m,d,nb,ctx)) + goto err; + + /* move the 'window' down further */ + wstart-=wend+1; + wvalue=0; + start=0; + if (wstart < 0) break; + } + ret=1; +err: + ctx->tos-=2; + for (i=0; i<16; i++) + if (val[i] != NULL) BN_clear_free(val[i]); + return(ret); + } +/* #endif */ + +/* #ifdef MONT_MUL_MOD */ +int BN_mod_exp_mont(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; + BIGNUM *d,*aa; + BIGNUM *val[16]; + BN_MONT_CTX *mont=NULL; + + if (!(m->d[0] & 1)) + { + BNerr(BN_F_BN_MOD_EXP_MONT,BN_R_CALLED_WITH_EVEN_MODULUS); + return(0); + } + d=ctx->bn[ctx->tos++]; + bits=BN_num_bits(p); + if (bits == 0) + { + BN_one(r); + return(1); + } + + /* If this is not done, things will break in the montgomery + * part */ + + if ((mont=BN_MONT_CTX_new()) == NULL) goto err; + if (!BN_MONT_CTX_set(mont,m,ctx)) goto err; + + val[0]=BN_new(); + if (BN_ucmp(a,m) >= 0) + { + BN_mod(val[0],a,m,ctx); + aa=val[0]; + } + else + aa=a; + if (!BN_to_montgomery(val[0],aa,mont,ctx)) goto err; /* 1 */ + if (!BN_mod_mul_montgomery(d,val[0],val[0],mont,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++) + { + val[i]=BN_new(); + if (!BN_mod_mul_montgomery(val[i],val[i-1],d,mont,ctx)) + goto err; + } + for (; i<16; i++) + val[i]=NULL; + + 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_to_montgomery(r,BN_value_one(),mont,ctx)) goto err; + for (;;) + { + if (BN_is_bit_set(p,wstart) == 0) + { + if (!start) + if (!BN_mod_mul_montgomery(r,r,r,mont,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_montgomery(r,r,r,mont,ctx)) + goto err; + } + + /* wvalue will be an odd number < 2^window */ + if (!BN_mod_mul_montgomery(r,r,val[wvalue>>1],mont,ctx)) + goto err; + + /* move the 'window' down further */ + wstart-=wend+1; + wvalue=0; + start=0; + if (wstart < 0) break; + } + BN_from_montgomery(r,r,mont,ctx); + ret=1; +err: + if (mont != NULL) BN_MONT_CTX_free(mont); + ctx->tos--; + for (i=0; i<16; i++) + if (val[i] != NULL) BN_clear_free(val[i]); + return(ret); + } +/* #endif */ + +/* The old fallback, simple version :-) */ +int BN_mod_exp_simple(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; + BIGNUM *d; + BIGNUM *val[16]; + + d=ctx->bn[ctx->tos++]; + bits=BN_num_bits(p); + + if (bits == 0) + { + BN_one(r); + return(1); + } + + val[0]=BN_new(); + if (!BN_mod(val[0],a,m,ctx)) goto err; /* 1 */ + if (!BN_mod_mul(d,val[0],val[0],m,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++) + { + val[i]=BN_new(); + if (!BN_mod_mul(val[i],val[i-1],d,m,ctx)) + goto err; + } + for (; i<16; i++) + val[i]=NULL; + + 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(r,r,r,m,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(r,r,r,m,ctx)) + goto err; + } + + /* wvalue will be an odd number < 2^window */ + if (!BN_mod_mul(r,r,val[wvalue>>1],m,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<16; i++) + if (val[i] != NULL) BN_clear_free(val[i]); + return(ret); + } + diff --git a/crypto/bn/bn_gcd.c b/crypto/bn/bn_gcd.c new file mode 100644 index 0000000000..9b0bc2b100 --- /dev/null +++ b/crypto/bn/bn_gcd.c @@ -0,0 +1,203 @@ +/* crypto/bn/bn_gcd.c */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include "cryptlib.h" +#include "bn_lcl.h" + +#ifndef NOPROTO +static BIGNUM *euclid(BIGNUM *a, BIGNUM *b); +#else +static BIGNUM *euclid(); +#endif + +int BN_gcd(r,in_a,in_b,ctx) +BIGNUM *r,*in_a,*in_b; +BN_CTX *ctx; + { + BIGNUM *a,*b,*t; + int ret=0; + + a=ctx->bn[ctx->tos]; + b=ctx->bn[ctx->tos+1]; + + if (BN_copy(a,in_a) == NULL) goto err; + if (BN_copy(b,in_b) == NULL) goto err; + + if (BN_cmp(a,b) < 0) { t=a; a=b; b=t; } + t=euclid(a,b); + if (t == NULL) goto err; + + if (BN_copy(r,t) == NULL) goto err; + ret=1; +err: + return(ret); + } + +static BIGNUM *euclid(a,b) +BIGNUM *a,*b; + { + BIGNUM *t; + int shifts=0; + + for (;;) + { + if (BN_is_zero(b)) + break; + + if (BN_is_odd(a)) + { + if (BN_is_odd(b)) + { + if (!BN_sub(a,a,b)) goto err; + if (!BN_rshift1(a,a)) goto err; + if (BN_cmp(a,b) < 0) + { t=a; a=b; b=t; } + } + else /* a odd - b even */ + { + if (!BN_rshift1(b,b)) goto err; + if (BN_cmp(a,b) < 0) + { t=a; a=b; b=t; } + } + } + else /* a is even */ + { + if (BN_is_odd(b)) + { + if (!BN_rshift1(a,a)) goto err; + if (BN_cmp(a,b) < 0) + { t=a; a=b; b=t; } + } + else /* a even - b even */ + { + if (!BN_rshift1(a,a)) goto err; + if (!BN_rshift1(b,b)) goto err; + shifts++; + } + } + } + if (shifts) + { + if (!BN_lshift(a,a,shifts)) goto err; + } + return(a); +err: + return(NULL); + } + +/* solves ax == 1 (mod n) */ +BIGNUM *BN_mod_inverse(a, n, ctx) +BIGNUM *a; +BIGNUM *n; +BN_CTX *ctx; + { + BIGNUM *A,*B,*X,*Y,*M,*D,*R; + BIGNUM *ret=NULL,*T; + int sign; + + A=ctx->bn[ctx->tos]; + B=ctx->bn[ctx->tos+1]; + X=ctx->bn[ctx->tos+2]; + D=ctx->bn[ctx->tos+3]; + M=ctx->bn[ctx->tos+4]; + Y=ctx->bn[ctx->tos+5]; + ctx->tos+=6; + R=BN_new(); + if (R == NULL) goto err; + + BN_zero(X); + BN_one(Y); + if (BN_copy(A,a) == NULL) goto err; + if (BN_copy(B,n) == NULL) goto err; + sign=1; + + while (!BN_is_zero(B)) + { + if (!BN_div(D,M,A,B,ctx)) goto err; + T=A; + A=B; + B=M; + /* T has a struct, M does not */ + + if (!BN_mul(T,D,X)) goto err; + if (!BN_add(T,T,Y)) goto err; + M=Y; + Y=X; + X=T; + sign= -sign; + } + if (sign < 0) + { + if (!BN_sub(Y,n,Y)) goto err; + } + + if (BN_is_one(A)) + { if (!BN_mod(R,Y,n,ctx)) goto err; } + else + { + BNerr(BN_F_BN_MOD_INVERSE,BN_R_NO_INVERSE); + goto err; + } + ret=R; +err: + if ((ret == NULL) && (R != NULL)) BN_free(R); + ctx->tos-=6; + return(ret); + } + diff --git a/crypto/bn/bn_lcl.h b/crypto/bn/bn_lcl.h new file mode 100644 index 0000000000..4d44651df8 --- /dev/null +++ b/crypto/bn/bn_lcl.h @@ -0,0 +1,216 @@ +/* crypto/bn/bn_lcl.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_BN_LCL_H +#define HEADER_BN_LCL_H + +#include "bn.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/************************************************************* + * Using the long long type + */ +#define Lw(t) (((BN_ULONG)(t))&BN_MASK2) +#define Hw(t) (((BN_ULONG)((t)>>BN_BITS2))&BN_MASK2) + +#define bn_fix_top(a) \ + { \ + BN_ULONG *fix_top_l; \ + for (fix_top_l= &((a)->d[(a)->top-1]); (a)->top > 0; (a)->top--) \ + if (*(fix_top_l--)) break; \ + } + +#define bn_expand(n,b) ((((b)/BN_BITS2) <= (n)->max)?(n):bn_expand2((n),(b))) + +#ifdef BN_LLONG +#define mul_add(r,a,w,c) { \ + BN_ULLONG t; \ + t=(BN_ULLONG)w * (a) + (r) + (c); \ + (r)=Lw(t); \ + (c)= Hw(t); \ + } + +#define mul(r,a,w,c) { \ + BN_ULLONG t; \ + t=(BN_ULLONG)w * (a) + (c); \ + (r)=Lw(t); \ + (c)= Hw(t); \ + } + +#define bn_mul_words(r1,r2,a,b) \ + { \ + BN_ULLONG t; \ + t=(BN_ULLONG)(a)*(b); \ + r1=Lw(t); \ + r2=Hw(t); \ + } + +#else +/************************************************************* + * No long long type + */ + +#define LBITS(a) ((a)&BN_MASK2l) +#define HBITS(a) (((a)>>BN_BITS4)&BN_MASK2l) +#define L2HBITS(a) ((BN_ULONG)((a)&BN_MASK2l)<<BN_BITS4) + +#define LLBITS(a) ((a)&BN_MASKl) +#define LHBITS(a) (((a)>>BN_BITS2)&BN_MASKl) +#define LL2HBITS(a) ((BN_ULLONG)((a)&BN_MASKl)<<BN_BITS2) + +#define mul64(l,h,bl,bh) \ + { \ + BN_ULONG m,m1,lt,ht; \ + \ + lt=l; \ + ht=h; \ + m =(bh)*(lt); \ + lt=(bl)*(lt); \ + m1=(bl)*(ht); \ + ht =(bh)*(ht); \ + m+=m1; if ((m&BN_MASK2) < m1) ht+=L2HBITS(1L); \ + ht+=HBITS(m); \ + m1=L2HBITS(m); \ + lt+=m1; if ((lt&BN_MASK2) < m1) ht++; \ + (l)=lt; \ + (h)=ht; \ + } + +#define sqr64(lo,ho,in) \ + { \ + BN_ULONG l,h,m; \ + \ + h=(in); \ + l=LBITS(h); \ + h=HBITS(h); \ + m =(l)*(h); \ + l*=l; \ + h*=h; \ + h+=(m&BN_MASK2h1)>>(BN_BITS4-1); \ + m =(m&BN_MASK2l)<<(BN_BITS4+1); \ + l+=m; if ((l&BN_MASK2) < m) h++; \ + (lo)=l; \ + (ho)=h; \ + } + +#define mul_add(r,a,bl,bh,c) { \ + BN_ULONG l,h; \ + \ + h= (a); \ + l=LBITS(h); \ + h=HBITS(h); \ + mul64(l,h,(bl),(bh)); \ + \ + /* non-multiply part */ \ + l+=(c); if ((l&BN_MASK2) < (c)) h++; \ + (c)=(r); \ + l+=(c); if ((l&BN_MASK2) < (c)) h++; \ + (c)=h&BN_MASK2; \ + (r)=l&BN_MASK2; \ + } + +#define mul(r,a,bl,bh,c) { \ + BN_ULONG l,h; \ + \ + h= (a); \ + l=LBITS(h); \ + h=HBITS(h); \ + mul64(l,h,(bl),(bh)); \ + \ + /* non-multiply part */ \ + l+=(c); if ((l&BN_MASK2) < (c)) h++; \ + (c)=h&BN_MASK2; \ + (r)=l&BN_MASK2; \ + } + +#define bn_mul_words(r1,r2,a,b) \ + { \ + BN_ULONG l,h,bl,bh; \ + \ + h=(a); \ + l=LBITS(h); \ + h=HBITS(h); \ + bh=(b); \ + bl=LBITS(bh); \ + bh=HBITS(bh); \ + \ + mul64(l,h,bl,bh); \ + \ + (r1)=l; \ + (r2)=h; \ + } +#endif + +#ifndef NOPROTO + +BIGNUM *bn_expand2(BIGNUM *b, int bits); + +#else + +BIGNUM *bn_expand2(); + +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/crypto/bn/bn_lib.c b/crypto/bn/bn_lib.c new file mode 100644 index 0000000000..288ebca68c --- /dev/null +++ b/crypto/bn/bn_lib.c @@ -0,0 +1,565 @@ +/* crypto/bn/bn_lib.c */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include "cryptlib.h" +#include "bn_lcl.h" + +char *BN_version="Big Number part of SSLeay 0.8.1b 29-Jun-1998"; + +BIGNUM *BN_value_one() + { + static BN_ULONG data_one=1L; + static BIGNUM const_one={&data_one,1,1,0}; + + return(&const_one); + } + +char *BN_options() + { + static int init=0; + static char data[16]; + + if (!init) + { + init++; +#ifdef BN_LLONG + sprintf(data,"bn(%d,%d)",(int)sizeof(BN_ULLONG)*8, + (int)sizeof(BN_ULONG)*8); +#else + sprintf(data,"bn(%d,%d)",(int)sizeof(BN_ULONG)*8, + (int)sizeof(BN_ULONG)*8); +#endif + } + return(data); + } + +int BN_num_bits_word(l) +BN_ULONG l; + { + static char bits[256]={ + 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + }; + +#ifdef SIXTY_FOUR_BIT_LONG + if (l & 0xffffffff00000000L) + { + if (l & 0xffff000000000000L) + { + if (l & 0xff00000000000000L) + { + return(bits[l>>56]+56); + } + else return(bits[l>>48]+48); + } + else + { + if (l & 0x0000ff0000000000L) + { + return(bits[l>>40]+40); + } + else return(bits[l>>32]+32); + } + } + else +#else +#ifdef SIXTY_FOUR_BIT + if (l & 0xffffffff00000000LL) + { + if (l & 0xffff000000000000LL) + { + if (l & 0xff00000000000000LL) + { + return(bits[l>>56]+56); + } + else return(bits[l>>48]+48); + } + else + { + if (l & 0x0000ff0000000000LL) + { + return(bits[l>>40]+40); + } + else return(bits[l>>32]+32); + } + } + else +#endif +#endif + { +#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG) + if (l & 0xffff0000L) + { + if (l & 0xff000000L) + return(bits[l>>24L]+24); + else return(bits[l>>16L]+16); + } + else +#endif + { +#if defined(SIXTEEN_BIT) || defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG) + if (l & 0xff00L) + return(bits[l>>8]+8); + else +#endif + return(bits[l ] ); + } + } + } + +int BN_num_bits(a) +BIGNUM *a; + { + BN_ULONG l; + int i; + + if (a->top == 0) return(0); + l=a->d[a->top-1]; + i=(a->top-1)*BN_BITS2; + if (l == 0) + { +#ifndef WIN16 + fprintf(stderr,"BAD TOP VALUE\n"); +#endif + abort(); + } + return(i+BN_num_bits_word(l)); + } + +void BN_clear_free(a) +BIGNUM *a; + { + if (a == NULL) return; + if (a->d != NULL) + { + memset(a->d,0,a->max*sizeof(a->d[0])); + Free(a->d); + } + memset(a,0,sizeof(BIGNUM)); + Free(a); + } + +void BN_free(a) +BIGNUM *a; + { + if (a == NULL) return; + if (a->d != NULL) Free(a->d); + Free(a); + } + +BIGNUM *BN_new() + { + BIGNUM *ret; + BN_ULONG *p; + + ret=(BIGNUM *)Malloc(sizeof(BIGNUM)); + if (ret == NULL) goto err; + ret->top=0; + ret->neg=0; + ret->max=(BN_DEFAULT_BITS/BN_BITS2); + p=(BN_ULONG *)Malloc(sizeof(BN_ULONG)*(ret->max+1)); + if (p == NULL) goto err; + ret->d=p; + + memset(p,0,(ret->max+1)*sizeof(p[0])); + return(ret); +err: + BNerr(BN_F_BN_NEW,ERR_R_MALLOC_FAILURE); + return(NULL); + } + +BN_CTX *BN_CTX_new() + { + BN_CTX *ret; + BIGNUM *n; + int i,j; + + ret=(BN_CTX *)Malloc(sizeof(BN_CTX)); + if (ret == NULL) goto err2; + + for (i=0; i<BN_CTX_NUM; i++) + { + n=BN_new(); + if (n == NULL) goto err; + ret->bn[i]=n; + } + + /* There is actually an extra one, this is for debugging my + * stuff */ + ret->bn[BN_CTX_NUM]=NULL; + + ret->tos=0; + return(ret); +err: + for (j=0; j<i; j++) + BN_free(ret->bn[j]); + Free(ret); +err2: + BNerr(BN_F_BN_CTX_NEW,ERR_R_MALLOC_FAILURE); + return(NULL); + } + +void BN_CTX_free(c) +BN_CTX *c; + { + int i; + + for (i=0; i<BN_CTX_NUM; i++) + BN_clear_free(c->bn[i]); + Free(c); + } + +BIGNUM *bn_expand2(b, bits) +BIGNUM *b; +int bits; + { + BN_ULONG *p; + register int n; + + while (bits > b->max*BN_BITS2) + { + n=((bits+BN_BITS2-1)/BN_BITS2)*2; + p=b->d=(BN_ULONG *)Realloc(b->d,sizeof(BN_ULONG)*(n+1)); + if (p == NULL) + { + BNerr(BN_F_BN_EXPAND2,ERR_R_MALLOC_FAILURE); + return(NULL); + } + memset(&(p[b->max]),0,((n+1)-b->max)*sizeof(BN_ULONG)); + b->max=n; + } + return(b); + } + +BIGNUM *BN_dup(a) +BIGNUM *a; + { + BIGNUM *r; + + r=BN_new(); + if (r == NULL) return(NULL); + return((BIGNUM *)BN_copy(r,a)); + } + +BIGNUM *BN_copy(a, b) +BIGNUM *a; +BIGNUM *b; + { + if (bn_expand(a,b->top*BN_BITS2) == NULL) return(NULL); + memcpy(a->d,b->d,sizeof(b->d[0])*b->top); +/* memset(&(a->d[b->top]),0,sizeof(a->d[0])*(a->max-b->top));*/ + a->top=b->top; + a->neg=b->neg; + return(a); + } + +void BN_clear(a) +BIGNUM *a; + { + memset(a->d,0,a->max*sizeof(a->d[0])); + a->top=0; + a->neg=0; + } + +unsigned long BN_get_word(a) +BIGNUM *a; + { + int i,n; + unsigned long ret=0; + + n=BN_num_bytes(a); + if (n > sizeof(unsigned long)) +#ifdef SIXTY_FOUR_BIT_LONG + return(BN_MASK2); +#else + return(0xFFFFFFFFL); +#endif + for (i=a->top-1; i>=0; i--) + { +#ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */ + ret<<=BN_BITS4; /* stops the compiler complaining */ + ret<<=BN_BITS4; +#endif + ret|=a->d[i]; + } + return(ret); + } + +int BN_set_word(a,w) +BIGNUM *a; +unsigned long w; + { + int i,n; + if (bn_expand(a,sizeof(unsigned long)*8) == NULL) return(0); + + n=sizeof(unsigned long)/BN_BYTES; + a->neg=0; + a->top=0; + a->d[0]=(BN_ULONG)w&BN_MASK2; + if (a->d[0] != 0) a->top=1; + for (i=1; i<n; i++) + { + /* the following is done instead of + * w>>=BN_BITS2 so compilers don't complain + * on builds where sizeof(long) == BN_TYPES */ +#ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */ + w>>=BN_BITS4; + w>>=BN_BITS4; +#endif + a->d[i]=(BN_ULONG)w&BN_MASK2; + if (a->d[i] != 0) a->top=i+1; + } + return(1); + } + +/* ignore negative */ +BIGNUM *BN_bin2bn(s, len, ret) +unsigned char *s; +int len; +BIGNUM *ret; + { + unsigned int i,m; + unsigned int n; + BN_ULONG l; + + if (ret == NULL) ret=BN_new(); + if (ret == NULL) return(NULL); + l=0; + n=len; + if (n == 0) + { + ret->top=0; + return(ret); + } + if (bn_expand(ret,(int)(n+2)*8) == NULL) + return(NULL); + i=((n-1)/BN_BYTES)+1; + m=((n-1)%(BN_BYTES)); + ret->top=i; + while (n-- > 0) + { + l=(l<<8L)| *(s++); + if (m-- == 0) + { + ret->d[--i]=l; + l=0; + m=BN_BYTES-1; + } + } + /* need to call this due to clear byte at top if avoiding + * having the top bit set (-ve number) */ + bn_fix_top(ret); + return(ret); + } + +/* ignore negative */ +int BN_bn2bin(a, to) +BIGNUM *a; +unsigned char *to; + { + int n,i; + BN_ULONG l; + + n=i=BN_num_bytes(a); + while (i-- > 0) + { + l=a->d[i/BN_BYTES]; + *(to++)=(unsigned char)(l>>(8*(i%BN_BYTES)))&0xff; + } + return(n); + } + +int BN_ucmp(a, b) +BIGNUM *a; +BIGNUM *b; + { + int i; + BN_ULONG t1,t2,*ap,*bp; + + i=a->top-b->top; + if (i != 0) return(i); + ap=a->d; + bp=b->d; + for (i=a->top-1; i>=0; i--) + { + t1= ap[i]; + t2= bp[i]; + if (t1 != t2) + return(t1 > t2?1:-1); + } + return(0); + } + +int BN_cmp(a, b) +BIGNUM *a; +BIGNUM *b; + { + int i; + int gt,lt; + BN_ULONG t1,t2; + + if ((a == NULL) || (b == NULL)) + { + if (a != NULL) + return(-1); + else if (b != NULL) + return(1); + else + return(0); + } + if (a->neg != b->neg) + { + if (a->neg) + return(-1); + else return(1); + } + if (a->neg == 0) + { gt=1; lt= -1; } + else { gt= -1; lt=1; } + + if (a->top > b->top) return(gt); + if (a->top < b->top) return(lt); + for (i=a->top-1; i>=0; i--) + { + t1=a->d[i]; + t2=b->d[i]; + if (t1 > t2) return(gt); + if (t1 < t2) return(lt); + } + return(0); + } + +int BN_set_bit(a, n) +BIGNUM *a; +int n; + { + int i,j; + + i=n/BN_BITS2; + j=n%BN_BITS2; + if (a->top <= i) return(0); + + a->d[i]|=(1L<<j); + return(1); + } + +int BN_clear_bit(a, n) +BIGNUM *a; +int n; + { + int i,j; + + i=n/BN_BITS2; + j=n%BN_BITS2; + if (a->top <= i) return(0); + + a->d[i]&=(~(1L<<j)); + return(1); + } + +int BN_is_bit_set(a, n) +BIGNUM *a; +int n; + { + int i,j; + + if (n < 0) return(0); + i=n/BN_BITS2; + j=n%BN_BITS2; + if (a->top <= i) return(0); + return((a->d[i]&(((BN_ULONG)1)<<j))?1:0); + } + +int BN_mask_bits(a,n) +BIGNUM *a; +int n; + { + int b,w; + + w=n/BN_BITS2; + b=n%BN_BITS2; + if (w >= a->top) return(0); + if (b == 0) + a->top=w; + else + { + a->top=w+1; + a->d[w]&= ~(BN_MASK2<<b); + while ((w >= 0) && (a->d[w] == 0)) + { + a->top--; + w--; + } + } + return(1); + } diff --git a/crypto/bn/bn_mod.c b/crypto/bn/bn_mod.c new file mode 100644 index 0000000000..c94241f59e --- /dev/null +++ b/crypto/bn/bn_mod.c @@ -0,0 +1,97 @@ +/* crypto/bn/bn_mod.c */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include "cryptlib.h" +#include "bn_lcl.h" + +/* rem != m */ +int BN_mod(rem, m, d,ctx) +BIGNUM *rem; +BIGNUM *m; +BIGNUM *d; +BN_CTX *ctx; + { +#if 0 /* The old slow way */ + int i,nm,nd; + BIGNUM *dv; + + if (BN_ucmp(m,d) < 0) + return((BN_copy(rem,m) == NULL)?0:1); + + dv=ctx->bn[ctx->tos]; + + if (!BN_copy(rem,m)) return(0); + + nm=BN_num_bits(rem); + nd=BN_num_bits(d); + if (!BN_lshift(dv,d,nm-nd)) return(0); + for (i=nm-nd; i>=0; i--) + { + if (BN_cmp(rem,dv) >= 0) + { + if (!BN_sub(rem,rem,dv)) return(0); + } + if (!BN_rshift1(dv,dv)) return(0); + } + return(1); +#else + return(BN_div(NULL,rem,m,d,ctx)); +#endif + } + diff --git a/crypto/bn/bn_mont.c b/crypto/bn/bn_mont.c new file mode 100644 index 0000000000..932d10b736 --- /dev/null +++ b/crypto/bn/bn_mont.c @@ -0,0 +1,280 @@ +/* crypto/bn/bn_mont.c */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include "cryptlib.h" +#include "bn_lcl.h" + +int BN_mod_mul_montgomery(r,a,b,mont,ctx) +BIGNUM *r,*a,*b; +BN_MONT_CTX *mont; +BN_CTX *ctx; + { + BIGNUM *tmp; + + tmp=ctx->bn[ctx->tos++]; + + if (a == b) + { + if (!BN_sqr(tmp,a,ctx)) goto err; + } + else + { + if (!BN_mul(tmp,a,b)) goto err; + } + /* reduce from aRR to aR */ + if (!BN_from_montgomery(r,tmp,mont,ctx)) goto err; + ctx->tos--; + return(1); +err: + return(0); + } + +#define MONT_WORD + +#ifdef MONT_WORD +int BN_from_montgomery(ret,a,mont,ctx) +BIGNUM *ret; +BIGNUM *a; +BN_MONT_CTX *mont; +BN_CTX *ctx; + { + BIGNUM *n,*t1,*r; + BN_ULONG *ap,*np,*rp,k,n0,v,v2; + int al,nl,max,i,x; + int retn=0; + + t1=ctx->bn[ctx->tos]; + r=ctx->bn[ctx->tos+1]; + + if (!BN_copy(r,a)) goto err; + n=mont->N; + + if (!BN_copy(t1,a)) goto err; + BN_mask_bits(t1,mont->ri); + + a=t1; + + al=a->top; + nl=n->top; + if ((al == 0) || (nl == 0)) { r->top=0; return(1); } + + max=(nl+al+1); /* allow for overflow (no?) XXX */ + if (bn_expand(r,(max)*BN_BITS2) == NULL) goto err; + + r->neg=a->neg^n->neg; + ap=a->d; + np=n->d; + rp=r->d; + + /* clear the top bytes of T */ + for (i=r->top; i<max; i++) /* memset? XXX */ + r->d[i]=0; +/* memset(&(r->d[r->top]),0,(max-r->top)*sizeof(BN_ULONG)); */ + + r->top=max; + n0=mont->n0; + + for (i=0; i<nl; i++) + { + /* This is were part words probably goes wrong */ + k=(rp[0]*n0)&BN_MASK2; + v=bn_mul_add_word(rp,np,nl,k); + + for (x=nl; v; x++) + { + v2=rp[x]; + v2+=v; + rp[x]=v2; + v=((v2&BN_MASK2) < v)?1:0; /* ever true? XXX */ + } + rp++; + } + while (r->d[r->top-1] == 0) + r->top--; + + BN_rshift(ret,r,mont->ri); + + if (BN_ucmp(ret,mont->N) >= 0) + { + bn_qsub(ret,ret,mont->N); /* XXX */ + } + retn=1; +err: + return(retn); + } +#else +int BN_from_montgomery(r,a,mont,ctx) +BIGNUM *r; +BIGNUM *a; +BN_MONT_CTX *mont; +BN_CTX *ctx; + { + BIGNUM *t1,*t2; + + t1=ctx->bn[ctx->tos]; + t2=ctx->bn[ctx->tos+1]; + + if (!BN_copy(t1,a)) goto err; + /* can cheat */ + BN_mask_bits(t1,mont->ri); + + if (!BN_mul(t2,t1,mont->Ni)) goto err; + BN_mask_bits(t2,mont->ri); + + if (!BN_mul(t1,t2,mont->N)) goto err; + if (!BN_add(t2,a,t1)) goto err; + BN_rshift(r,t2,mont->ri); + + if (BN_ucmp(r,mont->N) >= 0) + bn_qsub(r,r,mont->N); + + return(1); +err: + return(0); + } +#endif + +BN_MONT_CTX *BN_MONT_CTX_new() + { + BN_MONT_CTX *ret; + + if ((ret=(BN_MONT_CTX *)Malloc(sizeof(BN_MONT_CTX))) == NULL) + return(NULL); + ret->ri=0; + ret->RR=BN_new(); + ret->N=BN_new(); + ret->Ni=NULL; + if ((ret->RR == NULL) || (ret->N == NULL)) + { + BN_MONT_CTX_free(ret); + return(NULL); + } + return(ret); + } + +void BN_MONT_CTX_free(mont) +BN_MONT_CTX *mont; + { + if (mont->RR != NULL) BN_free(mont->RR); + if (mont->N != NULL) BN_free(mont->N); + if (mont->Ni != NULL) BN_free(mont->Ni); + Free(mont); + } + +int BN_MONT_CTX_set(mont,mod,ctx) +BN_MONT_CTX *mont; +BIGNUM *mod; +BN_CTX *ctx; + { + BIGNUM *Ri=NULL,*R=NULL; + + if (mont->RR == NULL) mont->RR=BN_new(); + if (mont->N == NULL) mont->N=BN_new(); + + R=mont->RR; /* grab RR as a temp */ + BN_copy(mont->N,mod); /* Set N */ + +#ifdef MONT_WORD +{ + BIGNUM tmod; + BN_ULONG buf[2]; + /* int z; */ + + mont->ri=(BN_num_bits(mod)+(BN_BITS2-1))/BN_BITS2*BN_BITS2; + BN_lshift(R,BN_value_one(),BN_BITS2); /* R */ + /* I was bad, this modification of a passed variable was + * breaking the multithreaded stuff :-( + * z=mod->top; + * mod->top=1; */ + + buf[0]=mod->d[0]; + buf[1]=0; + tmod.d=buf; + tmod.top=1; + tmod.max=mod->max; + tmod.neg=mod->neg; + + if ((Ri=BN_mod_inverse(R,&tmod,ctx)) == NULL) goto err; /* Ri */ + BN_lshift(Ri,Ri,BN_BITS2); /* R*Ri */ + bn_qsub(Ri,Ri,BN_value_one()); /* R*Ri - 1 */ + BN_div(Ri,NULL,Ri,&tmod,ctx); + mont->n0=Ri->d[0]; + BN_free(Ri); + /* mod->top=z; */ +} +#else + mont->ri=BN_num_bits(mod); + BN_lshift(R,BN_value_one(),mont->ri); /* R */ + if ((Ri=BN_mod_inverse(R,mod,ctx)) == NULL) goto err; /* Ri */ + BN_lshift(Ri,Ri,mont->ri); /* R*Ri */ + bn_qsub(Ri,Ri,BN_value_one()); /* R*Ri - 1 */ + BN_div(Ri,NULL,Ri,mod,ctx); + if (mont->Ni != NULL) BN_free(mont->Ni); + mont->Ni=Ri; /* Ni=(R*Ri-1)/N */ +#endif + + /* setup RR for conversions */ + BN_lshift(mont->RR,BN_value_one(),mont->ri*2); + BN_mod(mont->RR,mont->RR,mont->N,ctx); + + return(1); +err: + return(0); + } + diff --git a/crypto/bn/bn_mul.c b/crypto/bn/bn_mul.c new file mode 100644 index 0000000000..3c8bf23a70 --- /dev/null +++ b/crypto/bn/bn_mul.c @@ -0,0 +1,99 @@ +/* crypto/bn/bn_mul.c */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include "cryptlib.h" +#include "bn_lcl.h" + +/* r must be different to a and b */ +int BN_mul(r, a, b) +BIGNUM *r; +BIGNUM *a; +BIGNUM *b; + { + int i; + int max,al,bl; + BN_ULONG *ap,*bp,*rp; + + al=a->top; + bl=b->top; + if ((al == 0) || (bl == 0)) + { + r->top=0; + return(1); + } + + max=(al+bl); + if (bn_expand(r,(max)*BN_BITS2) == NULL) return(0); + r->top=max; + r->neg=a->neg^b->neg; + ap=a->d; + bp=b->d; + rp=r->d; + + rp[al]=bn_mul_word(rp,ap,al,*(bp++)); + rp++; + for (i=1; i<bl; i++) + { + rp[al]=bn_mul_add_word(rp,ap,al,*(bp++)); + rp++; + } + if (r->d[max-1] == 0) r->top--; + return(1); + } + diff --git a/crypto/bn/bn_mulw.c b/crypto/bn/bn_mulw.c new file mode 100644 index 0000000000..d903127395 --- /dev/null +++ b/crypto/bn/bn_mulw.c @@ -0,0 +1,303 @@ +/* crypto/bn/bn_mulw.c */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include "cryptlib.h" +#include "bn_lcl.h" + +#ifdef BN_LLONG + +BN_ULONG bn_mul_add_word(rp,ap,num,w) +BN_ULONG *rp,*ap; +int num; +BN_ULONG w; + { + BN_ULONG c1=0; + + 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; + } + + return(c1); + } + +BN_ULONG bn_mul_word(rp,ap,num,w) +BN_ULONG *rp,*ap; +int num; +BN_ULONG w; + { + BN_ULONG c1=0; + + 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; + } + return(c1); + } + +void bn_sqr_words(r,a,n) +BN_ULONG *r,*a; +int n; + { + 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; + } + } + +#else + +BN_ULONG bn_mul_add_word(rp,ap,num,w) +BN_ULONG *rp,*ap; +int num; +BN_ULONG w; + { + BN_ULONG c=0; + BN_ULONG bl,bh; + + bl=LBITS(w); + bh=HBITS(w); + + for (;;) + { + mul_add(rp[0],ap[0],bl,bh,c); + if (--num == 0) break; + mul_add(rp[1],ap[1],bl,bh,c); + if (--num == 0) break; + mul_add(rp[2],ap[2],bl,bh,c); + if (--num == 0) break; + mul_add(rp[3],ap[3],bl,bh,c); + if (--num == 0) break; + ap+=4; + rp+=4; + } + return(c); + } + +BN_ULONG bn_mul_word(rp,ap,num,w) +BN_ULONG *rp,*ap; +int num; +BN_ULONG w; + { + BN_ULONG carry=0; + BN_ULONG bl,bh; + + 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); + } + +void bn_sqr_words(r,a,n) +BN_ULONG *r,*a; +int n; + { + 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 + +#if defined(BN_LLONG) && defined(BN_DIV2W) + +BN_ULONG bn_div64(h,l,d) +BN_ULONG h,l,d; + { + return((BN_ULONG)(((((BN_ULLONG)h)<<BN_BITS2)|l)/(BN_ULLONG)d)); + } + +#else + +/* Divide h-l by d and return the result. */ +/* I need to test this some more :-( */ +BN_ULONG bn_div64(h,l,d) +BN_ULONG h,l,d; + { + BN_ULONG dh,dl,q,ret=0,th,tl,t; + int i,count=2; + + if (d == 0) return(BN_MASK2); + + i=BN_num_bits_word(d); + if ((i != BN_BITS2) && (h > (BN_ULONG)1<<i)) + { +#ifndef WIN16 + fprintf(stderr,"Division would overflow (%d)\n",i); +#endif + abort(); + } + i=BN_BITS2-i; + if (h >= d) h-=d; + + if (i) + { + d<<=i; + h=(h<<i)|(l>>(BN_BITS2-i)); + l<<=i; + } + dh=(d&BN_MASK2h)>>BN_BITS4; + dl=(d&BN_MASK2l); + for (;;) + { + if ((h>>BN_BITS4) == dh) + q=BN_MASK2l; + else + q=h/dh; + + for (;;) + { + t=(h-q*dh); + if ((t&BN_MASK2h) || + ((dl*q) <= ( + (t<<BN_BITS4)+ + ((l&BN_MASK2h)>>BN_BITS4)))) + break; + q--; + } + th=q*dh; + tl=q*dl; + t=(tl>>BN_BITS4); + tl=(tl<<BN_BITS4)&BN_MASK2h; + th+=t; + + if (l < tl) th++; + l-=tl; + if (h < th) + { + h+=d; + q--; + } + h-=th; + + if (--count == 0) break; + + ret=q<<BN_BITS4; + h=((h<<BN_BITS4)|(l>>BN_BITS4))&BN_MASK2; + l=(l&BN_MASK2l)<<BN_BITS4; + } + ret|=q; + return(ret); + } +#endif + diff --git a/crypto/bn/bn_prime.c b/crypto/bn/bn_prime.c new file mode 100644 index 0000000000..07a8289492 --- /dev/null +++ b/crypto/bn/bn_prime.c @@ -0,0 +1,389 @@ +/* crypto/bn/bn_prime.c */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include <time.h> +#include "cryptlib.h" +#include "bn_lcl.h" +#include "rand.h" + +/* The quick seive algorithm approach to weeding out primes is + * Philip Zimmermann's, as implemented in PGP. I have had a read of + * his comments and implemented my own version. + */ +#include "bn_prime.h" + +#ifndef NOPROTO +static int witness(BIGNUM *a, BIGNUM *n, BN_CTX *ctx); +static int probable_prime(BIGNUM *rnd, int bits); +static int probable_prime_dh(BIGNUM *rnd, int bits, + BIGNUM *add, BIGNUM *rem, BN_CTX *ctx); +static int probable_prime_dh_strong(BIGNUM *rnd, int bits, + BIGNUM *add, BIGNUM *rem, BN_CTX *ctx); +#else +static int witness(); +static int probable_prime(); +static int probable_prime_dh(); +static int probable_prime_dh_strong(); +#endif + +BIGNUM *BN_generate_prime(bits,strong,add,rem,callback) +int bits; +int strong; +BIGNUM *add; +BIGNUM *rem; +void (*callback)(P_I_I); + { + BIGNUM *rnd=NULL; + BIGNUM *ret=NULL; + BIGNUM *t=NULL; + int i,j,c1=0; + BN_CTX *ctx; + + ctx=BN_CTX_new(); + if (ctx == NULL) goto err; + if ((rnd=BN_new()) == NULL) goto err; + if (strong) + if ((t=BN_new()) == NULL) goto err; +loop: + /* make a random number and set the top and bottom bits */ + if (add == NULL) + { + if (!probable_prime(rnd,bits)) goto err; + } + else + { + if (strong) + { + if (!probable_prime_dh_strong(rnd,bits,add,rem,ctx)) + goto err; + } + else + { + if (!probable_prime_dh(rnd,bits,add,rem,ctx)) + goto err; + } + } + /* if (BN_mod_word(rnd,(BN_ULONG)3) == 1) goto loop; */ + if (callback != NULL) callback(0,c1++); + + if (!strong) + { + i=BN_is_prime(rnd,BN_prime_checks,callback,ctx); + if (i == -1) goto err; + if (i == 0) goto loop; + } + else + { + /* for a strong prime generation, + * check that (p-1)/2 is prime. + * Since a prime is odd, We just + * need to divide by 2 */ + if (!BN_rshift1(t,rnd)) goto err; + + for (i=0; i<BN_prime_checks; i++) + { + j=BN_is_prime(rnd,1,callback,ctx); + if (j == -1) goto err; + if (j == 0) goto loop; + + j=BN_is_prime(t,1,callback,ctx); + if (j == -1) goto err; + if (j == 0) goto loop; + + if (callback != NULL) callback(2,c1-1); + /* We have a strong prime test pass */ + } + } + /* we have a prime :-) */ + ret=rnd; +err: + if ((ret == NULL) && (rnd != NULL)) BN_free(rnd); + if (t != NULL) BN_free(t); + if (ctx != NULL) BN_CTX_free(ctx); + return(ret); + } + +int BN_is_prime(a,checks,callback,ctx_passed) +BIGNUM *a; +int checks; +void (*callback)(P_I_I); +BN_CTX *ctx_passed; + { + int i,j,c2=0,ret= -1; + BIGNUM *check; + BN_CTX *ctx; + + if (ctx_passed != NULL) + ctx=ctx_passed; + else + if ((ctx=BN_CTX_new()) == NULL) goto err; + + check=ctx->bn[ctx->tos++]; + for (i=0; i<checks; i++) + { + if (!BN_rand(check,BN_num_bits(a)-1,0,0)) goto err; + j=witness(check,a,ctx); + if (j == -1) goto err; + if (j) + { + ret=0; + goto err; + } + if (callback != NULL) callback(1,c2++); + } + ret=1; +err: + ctx->tos--; + if ((ctx_passed == NULL) && (ctx != NULL)) + BN_CTX_free(ctx); + + return(ret); + } + +#define RECP_MUL_MOD + +static int witness(a, n,ctx) +BIGNUM *a; +BIGNUM *n; +BN_CTX *ctx; + { + int k,i,nb,ret= -1; + BIGNUM *d,*dd,*tmp; + BIGNUM *d1,*d2,*x,*n1,*inv; + + d1=ctx->bn[ctx->tos]; + d2=ctx->bn[ctx->tos+1]; + x=ctx->bn[ctx->tos+2]; + n1=ctx->bn[ctx->tos+3]; + inv=ctx->bn[ctx->tos+4]; + ctx->tos+=5; + + d=d1; + dd=d2; + if (!BN_one(d)) goto err; + if (!BN_sub(n1,n,d)) goto err; /* n1=n-1; */ + k=BN_num_bits(n1); + + /* i=BN_num_bits(n); */ +#ifdef RECP_MUL_MOD + nb=BN_reciprocal(inv,n,ctx); /**/ + if (nb == -1) goto err; +#endif + + for (i=k-1; i>=0; i--) + { + if (BN_copy(x,d) == NULL) goto err; +#ifndef RECP_MUL_MOD + if (!BN_mod_mul(dd,d,d,n,ctx)) goto err; +#else + if (!BN_mod_mul_reciprocal(dd,d,d,n,inv,nb,ctx)) goto err; +#endif + if ( BN_is_one(dd) && + !BN_is_one(x) && + (BN_cmp(x,n1) != 0)) + { + ret=1; + goto err; + } + if (BN_is_bit_set(n1,i)) + { +#ifndef RECP_MUL_MOD + if (!BN_mod_mul(d,dd,a,n,ctx)) goto err; +#else + if (!BN_mod_mul_reciprocal(d,dd,a,n,inv,nb,ctx)) goto err; +#endif + } + else + { + tmp=d; + d=dd; + dd=tmp; + } + } + if (BN_is_one(d)) + i=0; + else i=1; + ret=i; +err: + ctx->tos-=5; + return(ret); + } + +static int probable_prime(rnd, bits) +BIGNUM *rnd; +int bits; + { + int i; + MS_STATIC BN_ULONG mods[NUMPRIMES]; + BN_ULONG delta; + + if (!BN_rand(rnd,bits,1,1)) return(0); + /* we now have a random number 'rand' to test. */ + for (i=1; i<NUMPRIMES; i++) + mods[i]=BN_mod_word(rnd,(BN_ULONG)primes[i]); + delta=0; + loop: for (i=1; i<NUMPRIMES; i++) + { + /* check that rnd is not a prime and also + * that gcd(rnd-1,primes) == 1 (except for 2) */ + if (((mods[i]+delta)%primes[i]) <= 1) + { + delta+=2; + /* perhaps need to check for overflow of + * delta (but delta can be upto 2^32) */ + goto loop; + } + } + if (!BN_add_word(rnd,delta)) return(0); + return(1); + } + +static int probable_prime_dh(rnd, bits, add, rem,ctx) +BIGNUM *rnd; +int bits; +BIGNUM *add; +BIGNUM *rem; +BN_CTX *ctx; + { + int i,ret=0; + BIGNUM *t1; + + t1=ctx->bn[ctx->tos++]; + + if (!BN_rand(rnd,bits,0,1)) goto err; + + /* we need ((rnd-rem) % add) == 0 */ + + if (!BN_mod(t1,rnd,add,ctx)) goto err; + if (!BN_sub(rnd,rnd,t1)) goto err; + if (rem == NULL) + { if (!BN_add_word(rnd,1)) goto err; } + else + { if (!BN_add(rnd,rnd,rem)) goto err; } + + /* we now have a random number 'rand' to test. */ + + loop: for (i=1; i<NUMPRIMES; i++) + { + /* check that rnd is a prime */ + if (BN_mod_word(rnd,(BN_LONG)primes[i]) <= 1) + { + if (!BN_add(rnd,rnd,add)) goto err; + goto loop; + } + } + ret=1; +err: + ctx->tos--; + return(ret); + } + +static int probable_prime_dh_strong(p, bits, padd, rem,ctx) +BIGNUM *p; +int bits; +BIGNUM *padd; +BIGNUM *rem; +BN_CTX *ctx; + { + int i,ret=0; + BIGNUM *t1,*qadd=NULL,*q=NULL; + + bits--; + t1=ctx->bn[ctx->tos++]; + q=ctx->bn[ctx->tos++]; + qadd=ctx->bn[ctx->tos++]; + + if (!BN_rshift1(qadd,padd)) goto err; + + if (!BN_rand(q,bits,0,1)) goto err; + + /* we need ((rnd-rem) % add) == 0 */ + if (!BN_mod(t1,q,qadd,ctx)) goto err; + if (!BN_sub(q,q,t1)) goto err; + if (rem == NULL) + { if (!BN_add_word(q,1)) goto err; } + else + { + if (!BN_rshift1(t1,rem)) goto err; + if (!BN_add(q,q,t1)) goto err; + } + + /* we now have a random number 'rand' to test. */ + if (!BN_lshift1(p,q)) goto err; + if (!BN_add_word(p,1)) goto err; + + loop: for (i=1; i<NUMPRIMES; i++) + { + /* check that p and q are prime */ + /* check that for p and q + * gcd(p-1,primes) == 1 (except for 2) */ + if ( (BN_mod_word(p,(BN_LONG)primes[i]) == 0) || + (BN_mod_word(q,(BN_LONG)primes[i]) == 0)) + { + if (!BN_add(p,p,padd)) goto err; + if (!BN_add(q,q,qadd)) goto err; + goto loop; + } + } + ret=1; +err: + ctx->tos-=3; + return(ret); + } + diff --git a/crypto/bn/bn_prime.h b/crypto/bn/bn_prime.h new file mode 100644 index 0000000000..1d6df587a8 --- /dev/null +++ b/crypto/bn/bn_prime.h @@ -0,0 +1,325 @@ +/* crypto/bn/bn_prime.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef EIGHT_BIT +#define NUMPRIMES 2048 +#else +#define NUMPRIMES 54 +#endif +static unsigned int primes[NUMPRIMES]= + { + 2, 3, 5, 7, 11, 13, 17, 19, + 23, 29, 31, 37, 41, 43, 47, 53, + 59, 61, 67, 71, 73, 79, 83, 89, + 97, 101, 103, 107, 109, 113, 127, 131, + 137, 139, 149, 151, 157, 163, 167, 173, + 179, 181, 191, 193, 197, 199, 211, 223, + 227, 229, 233, 239, 241, 251, +#ifndef EIGHT_BIT + 257, 263, + 269, 271, 277, 281, 283, 293, 307, 311, + 313, 317, 331, 337, 347, 349, 353, 359, + 367, 373, 379, 383, 389, 397, 401, 409, + 419, 421, 431, 433, 439, 443, 449, 457, + 461, 463, 467, 479, 487, 491, 499, 503, + 509, 521, 523, 541, 547, 557, 563, 569, + 571, 577, 587, 593, 599, 601, 607, 613, + 617, 619, 631, 641, 643, 647, 653, 659, + 661, 673, 677, 683, 691, 701, 709, 719, + 727, 733, 739, 743, 751, 757, 761, 769, + 773, 787, 797, 809, 811, 821, 823, 827, + 829, 839, 853, 857, 859, 863, 877, 881, + 883, 887, 907, 911, 919, 929, 937, 941, + 947, 953, 967, 971, 977, 983, 991, 997, + 1009,1013,1019,1021,1031,1033,1039,1049, + 1051,1061,1063,1069,1087,1091,1093,1097, + 1103,1109,1117,1123,1129,1151,1153,1163, + 1171,1181,1187,1193,1201,1213,1217,1223, + 1229,1231,1237,1249,1259,1277,1279,1283, + 1289,1291,1297,1301,1303,1307,1319,1321, + 1327,1361,1367,1373,1381,1399,1409,1423, + 1427,1429,1433,1439,1447,1451,1453,1459, + 1471,1481,1483,1487,1489,1493,1499,1511, + 1523,1531,1543,1549,1553,1559,1567,1571, + 1579,1583,1597,1601,1607,1609,1613,1619, + 1621,1627,1637,1657,1663,1667,1669,1693, + 1697,1699,1709,1721,1723,1733,1741,1747, + 1753,1759,1777,1783,1787,1789,1801,1811, + 1823,1831,1847,1861,1867,1871,1873,1877, + 1879,1889,1901,1907,1913,1931,1933,1949, + 1951,1973,1979,1987,1993,1997,1999,2003, + 2011,2017,2027,2029,2039,2053,2063,2069, + 2081,2083,2087,2089,2099,2111,2113,2129, + 2131,2137,2141,2143,2153,2161,2179,2203, + 2207,2213,2221,2237,2239,2243,2251,2267, + 2269,2273,2281,2287,2293,2297,2309,2311, + 2333,2339,2341,2347,2351,2357,2371,2377, + 2381,2383,2389,2393,2399,2411,2417,2423, + 2437,2441,2447,2459,2467,2473,2477,2503, + 2521,2531,2539,2543,2549,2551,2557,2579, + 2591,2593,2609,2617,2621,2633,2647,2657, + 2659,2663,2671,2677,2683,2687,2689,2693, + 2699,2707,2711,2713,2719,2729,2731,2741, + 2749,2753,2767,2777,2789,2791,2797,2801, + 2803,2819,2833,2837,2843,2851,2857,2861, + 2879,2887,2897,2903,2909,2917,2927,2939, + 2953,2957,2963,2969,2971,2999,3001,3011, + 3019,3023,3037,3041,3049,3061,3067,3079, + 3083,3089,3109,3119,3121,3137,3163,3167, + 3169,3181,3187,3191,3203,3209,3217,3221, + 3229,3251,3253,3257,3259,3271,3299,3301, + 3307,3313,3319,3323,3329,3331,3343,3347, + 3359,3361,3371,3373,3389,3391,3407,3413, + 3433,3449,3457,3461,3463,3467,3469,3491, + 3499,3511,3517,3527,3529,3533,3539,3541, + 3547,3557,3559,3571,3581,3583,3593,3607, + 3613,3617,3623,3631,3637,3643,3659,3671, + 3673,3677,3691,3697,3701,3709,3719,3727, + 3733,3739,3761,3767,3769,3779,3793,3797, + 3803,3821,3823,3833,3847,3851,3853,3863, + 3877,3881,3889,3907,3911,3917,3919,3923, + 3929,3931,3943,3947,3967,3989,4001,4003, + 4007,4013,4019,4021,4027,4049,4051,4057, + 4073,4079,4091,4093,4099,4111,4127,4129, + 4133,4139,4153,4157,4159,4177,4201,4211, + 4217,4219,4229,4231,4241,4243,4253,4259, + 4261,4271,4273,4283,4289,4297,4327,4337, + 4339,4349,4357,4363,4373,4391,4397,4409, + 4421,4423,4441,4447,4451,4457,4463,4481, + 4483,4493,4507,4513,4517,4519,4523,4547, + 4549,4561,4567,4583,4591,4597,4603,4621, + 4637,4639,4643,4649,4651,4657,4663,4673, + 4679,4691,4703,4721,4723,4729,4733,4751, + 4759,4783,4787,4789,4793,4799,4801,4813, + 4817,4831,4861,4871,4877,4889,4903,4909, + 4919,4931,4933,4937,4943,4951,4957,4967, + 4969,4973,4987,4993,4999,5003,5009,5011, + 5021,5023,5039,5051,5059,5077,5081,5087, + 5099,5101,5107,5113,5119,5147,5153,5167, + 5171,5179,5189,5197,5209,5227,5231,5233, + 5237,5261,5273,5279,5281,5297,5303,5309, + 5323,5333,5347,5351,5381,5387,5393,5399, + 5407,5413,5417,5419,5431,5437,5441,5443, + 5449,5471,5477,5479,5483,5501,5503,5507, + 5519,5521,5527,5531,5557,5563,5569,5573, + 5581,5591,5623,5639,5641,5647,5651,5653, + 5657,5659,5669,5683,5689,5693,5701,5711, + 5717,5737,5741,5743,5749,5779,5783,5791, + 5801,5807,5813,5821,5827,5839,5843,5849, + 5851,5857,5861,5867,5869,5879,5881,5897, + 5903,5923,5927,5939,5953,5981,5987,6007, + 6011,6029,6037,6043,6047,6053,6067,6073, + 6079,6089,6091,6101,6113,6121,6131,6133, + 6143,6151,6163,6173,6197,6199,6203,6211, + 6217,6221,6229,6247,6257,6263,6269,6271, + 6277,6287,6299,6301,6311,6317,6323,6329, + 6337,6343,6353,6359,6361,6367,6373,6379, + 6389,6397,6421,6427,6449,6451,6469,6473, + 6481,6491,6521,6529,6547,6551,6553,6563, + 6569,6571,6577,6581,6599,6607,6619,6637, + 6653,6659,6661,6673,6679,6689,6691,6701, + 6703,6709,6719,6733,6737,6761,6763,6779, + 6781,6791,6793,6803,6823,6827,6829,6833, + 6841,6857,6863,6869,6871,6883,6899,6907, + 6911,6917,6947,6949,6959,6961,6967,6971, + 6977,6983,6991,6997,7001,7013,7019,7027, + 7039,7043,7057,7069,7079,7103,7109,7121, + 7127,7129,7151,7159,7177,7187,7193,7207, + 7211,7213,7219,7229,7237,7243,7247,7253, + 7283,7297,7307,7309,7321,7331,7333,7349, + 7351,7369,7393,7411,7417,7433,7451,7457, + 7459,7477,7481,7487,7489,7499,7507,7517, + 7523,7529,7537,7541,7547,7549,7559,7561, + 7573,7577,7583,7589,7591,7603,7607,7621, + 7639,7643,7649,7669,7673,7681,7687,7691, + 7699,7703,7717,7723,7727,7741,7753,7757, + 7759,7789,7793,7817,7823,7829,7841,7853, + 7867,7873,7877,7879,7883,7901,7907,7919, + 7927,7933,7937,7949,7951,7963,7993,8009, + 8011,8017,8039,8053,8059,8069,8081,8087, + 8089,8093,8101,8111,8117,8123,8147,8161, + 8167,8171,8179,8191,8209,8219,8221,8231, + 8233,8237,8243,8263,8269,8273,8287,8291, + 8293,8297,8311,8317,8329,8353,8363,8369, + 8377,8387,8389,8419,8423,8429,8431,8443, + 8447,8461,8467,8501,8513,8521,8527,8537, + 8539,8543,8563,8573,8581,8597,8599,8609, + 8623,8627,8629,8641,8647,8663,8669,8677, + 8681,8689,8693,8699,8707,8713,8719,8731, + 8737,8741,8747,8753,8761,8779,8783,8803, + 8807,8819,8821,8831,8837,8839,8849,8861, + 8863,8867,8887,8893,8923,8929,8933,8941, + 8951,8963,8969,8971,8999,9001,9007,9011, + 9013,9029,9041,9043,9049,9059,9067,9091, + 9103,9109,9127,9133,9137,9151,9157,9161, + 9173,9181,9187,9199,9203,9209,9221,9227, + 9239,9241,9257,9277,9281,9283,9293,9311, + 9319,9323,9337,9341,9343,9349,9371,9377, + 9391,9397,9403,9413,9419,9421,9431,9433, + 9437,9439,9461,9463,9467,9473,9479,9491, + 9497,9511,9521,9533,9539,9547,9551,9587, + 9601,9613,9619,9623,9629,9631,9643,9649, + 9661,9677,9679,9689,9697,9719,9721,9733, + 9739,9743,9749,9767,9769,9781,9787,9791, + 9803,9811,9817,9829,9833,9839,9851,9857, + 9859,9871,9883,9887,9901,9907,9923,9929, + 9931,9941,9949,9967,9973,10007,10009,10037, + 10039,10061,10067,10069,10079,10091,10093,10099, + 10103,10111,10133,10139,10141,10151,10159,10163, + 10169,10177,10181,10193,10211,10223,10243,10247, + 10253,10259,10267,10271,10273,10289,10301,10303, + 10313,10321,10331,10333,10337,10343,10357,10369, + 10391,10399,10427,10429,10433,10453,10457,10459, + 10463,10477,10487,10499,10501,10513,10529,10531, + 10559,10567,10589,10597,10601,10607,10613,10627, + 10631,10639,10651,10657,10663,10667,10687,10691, + 10709,10711,10723,10729,10733,10739,10753,10771, + 10781,10789,10799,10831,10837,10847,10853,10859, + 10861,10867,10883,10889,10891,10903,10909,10937, + 10939,10949,10957,10973,10979,10987,10993,11003, + 11027,11047,11057,11059,11069,11071,11083,11087, + 11093,11113,11117,11119,11131,11149,11159,11161, + 11171,11173,11177,11197,11213,11239,11243,11251, + 11257,11261,11273,11279,11287,11299,11311,11317, + 11321,11329,11351,11353,11369,11383,11393,11399, + 11411,11423,11437,11443,11447,11467,11471,11483, + 11489,11491,11497,11503,11519,11527,11549,11551, + 11579,11587,11593,11597,11617,11621,11633,11657, + 11677,11681,11689,11699,11701,11717,11719,11731, + 11743,11777,11779,11783,11789,11801,11807,11813, + 11821,11827,11831,11833,11839,11863,11867,11887, + 11897,11903,11909,11923,11927,11933,11939,11941, + 11953,11959,11969,11971,11981,11987,12007,12011, + 12037,12041,12043,12049,12071,12073,12097,12101, + 12107,12109,12113,12119,12143,12149,12157,12161, + 12163,12197,12203,12211,12227,12239,12241,12251, + 12253,12263,12269,12277,12281,12289,12301,12323, + 12329,12343,12347,12373,12377,12379,12391,12401, + 12409,12413,12421,12433,12437,12451,12457,12473, + 12479,12487,12491,12497,12503,12511,12517,12527, + 12539,12541,12547,12553,12569,12577,12583,12589, + 12601,12611,12613,12619,12637,12641,12647,12653, + 12659,12671,12689,12697,12703,12713,12721,12739, + 12743,12757,12763,12781,12791,12799,12809,12821, + 12823,12829,12841,12853,12889,12893,12899,12907, + 12911,12917,12919,12923,12941,12953,12959,12967, + 12973,12979,12983,13001,13003,13007,13009,13033, + 13037,13043,13049,13063,13093,13099,13103,13109, + 13121,13127,13147,13151,13159,13163,13171,13177, + 13183,13187,13217,13219,13229,13241,13249,13259, + 13267,13291,13297,13309,13313,13327,13331,13337, + 13339,13367,13381,13397,13399,13411,13417,13421, + 13441,13451,13457,13463,13469,13477,13487,13499, + 13513,13523,13537,13553,13567,13577,13591,13597, + 13613,13619,13627,13633,13649,13669,13679,13681, + 13687,13691,13693,13697,13709,13711,13721,13723, + 13729,13751,13757,13759,13763,13781,13789,13799, + 13807,13829,13831,13841,13859,13873,13877,13879, + 13883,13901,13903,13907,13913,13921,13931,13933, + 13963,13967,13997,13999,14009,14011,14029,14033, + 14051,14057,14071,14081,14083,14087,14107,14143, + 14149,14153,14159,14173,14177,14197,14207,14221, + 14243,14249,14251,14281,14293,14303,14321,14323, + 14327,14341,14347,14369,14387,14389,14401,14407, + 14411,14419,14423,14431,14437,14447,14449,14461, + 14479,14489,14503,14519,14533,14537,14543,14549, + 14551,14557,14561,14563,14591,14593,14621,14627, + 14629,14633,14639,14653,14657,14669,14683,14699, + 14713,14717,14723,14731,14737,14741,14747,14753, + 14759,14767,14771,14779,14783,14797,14813,14821, + 14827,14831,14843,14851,14867,14869,14879,14887, + 14891,14897,14923,14929,14939,14947,14951,14957, + 14969,14983,15013,15017,15031,15053,15061,15073, + 15077,15083,15091,15101,15107,15121,15131,15137, + 15139,15149,15161,15173,15187,15193,15199,15217, + 15227,15233,15241,15259,15263,15269,15271,15277, + 15287,15289,15299,15307,15313,15319,15329,15331, + 15349,15359,15361,15373,15377,15383,15391,15401, + 15413,15427,15439,15443,15451,15461,15467,15473, + 15493,15497,15511,15527,15541,15551,15559,15569, + 15581,15583,15601,15607,15619,15629,15641,15643, + 15647,15649,15661,15667,15671,15679,15683,15727, + 15731,15733,15737,15739,15749,15761,15767,15773, + 15787,15791,15797,15803,15809,15817,15823,15859, + 15877,15881,15887,15889,15901,15907,15913,15919, + 15923,15937,15959,15971,15973,15991,16001,16007, + 16033,16057,16061,16063,16067,16069,16073,16087, + 16091,16097,16103,16111,16127,16139,16141,16183, + 16187,16189,16193,16217,16223,16229,16231,16249, + 16253,16267,16273,16301,16319,16333,16339,16349, + 16361,16363,16369,16381,16411,16417,16421,16427, + 16433,16447,16451,16453,16477,16481,16487,16493, + 16519,16529,16547,16553,16561,16567,16573,16603, + 16607,16619,16631,16633,16649,16651,16657,16661, + 16673,16691,16693,16699,16703,16729,16741,16747, + 16759,16763,16787,16811,16823,16829,16831,16843, + 16871,16879,16883,16889,16901,16903,16921,16927, + 16931,16937,16943,16963,16979,16981,16987,16993, + 17011,17021,17027,17029,17033,17041,17047,17053, + 17077,17093,17099,17107,17117,17123,17137,17159, + 17167,17183,17189,17191,17203,17207,17209,17231, + 17239,17257,17291,17293,17299,17317,17321,17327, + 17333,17341,17351,17359,17377,17383,17387,17389, + 17393,17401,17417,17419,17431,17443,17449,17467, + 17471,17477,17483,17489,17491,17497,17509,17519, + 17539,17551,17569,17573,17579,17581,17597,17599, + 17609,17623,17627,17657,17659,17669,17681,17683, + 17707,17713,17729,17737,17747,17749,17761,17783, + 17789,17791,17807,17827,17837,17839,17851,17863, +#endif + }; diff --git a/crypto/bn/bn_prime.pl b/crypto/bn/bn_prime.pl new file mode 100644 index 0000000000..979385a334 --- /dev/null +++ b/crypto/bn/bn_prime.pl @@ -0,0 +1,56 @@ +#!/usr/local/bin/perl +# bn_prime.pl + +$num=2048; +$num=$ARGV[0] if ($#ARGV >= 0); + +push(@primes,2); +$p=1; +loop: while ($#primes < $num-1) + { + $p+=2; + $s=int(sqrt($p)); + + for ($i=0; $primes[$i]<=$s; $i++) + { + next loop if (($p%$primes[$i]) == 0); + } + push(@primes,$p); + } + +print <<"EOF"; +/* Auto generated by bn_prime.pl */ +/* Copyright (C) 1995-1997 Eric Young (eay\@mincom.oz.au). + * All rights reserved. + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * See the COPYRIGHT file in the SSLeay distribution for more details. + */ + +EOF + +for ($i=0; $i <= $#primes; $i++) + { + if ($primes[$i] > 256) + { + $eight=$i; + last; + } + } + +printf "#ifndef EIGHT_BIT\n"; +printf "#define NUMPRIMES %d\n",$num; +printf "#else\n"; +printf "#define NUMPRIMES %d\n",$eight; +printf "#endif\n"; +print "static unsigned int primes[NUMPRIMES]=\n\t{\n\t"; +$init=0; +for ($i=0; $i <= $#primes; $i++) + { + printf "\n#ifndef EIGHT_BIT\n\t" if ($primes[$i] > 256) && !($init++); + printf("\n\t") if (($i%8) == 0) && ($i != 0); + printf("%4d,",$primes[$i]); + } +print "\n#endif\n\t};\n"; + + diff --git a/crypto/bn/bn_print.c b/crypto/bn/bn_print.c new file mode 100644 index 0000000000..36bc0d1430 --- /dev/null +++ b/crypto/bn/bn_print.c @@ -0,0 +1,218 @@ +/* crypto/bn/bn_print.c */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include <ctype.h> +#include "cryptlib.h" +#include "buffer.h" +#include "bn_lcl.h" + +static char *Hex="0123456789ABCDEF"; + +/* Must 'Free' the returned data */ +char *BN_bn2ascii(a) +BIGNUM *a; + { + int i,j,v,z=0; + char *buf; + char *p; + + buf=(char *)Malloc(a->top*BN_BYTES*2+2); + if (buf == NULL) + { + BNerr(BN_F_BN_BN2ASCII,ERR_R_MALLOC_FAILURE); + goto err; + } + p=buf; + if (a->neg) *(p++)='-'; + if (a->top == 0) *(p++)='0'; + for (i=a->top-1; i >=0; i--) + { + for (j=BN_BITS2-8; j >= 0; j-=8) + { + /* strip leading zeros */ + v=((int)(a->d[i]>>(long)j))&0xff; + if (z || (v != 0)) + { + *(p++)=Hex[v>>4]; + *(p++)=Hex[v&0x0f]; + z=1; + } + } + } + *p='\0'; +err: + return(buf); + } + +int BN_ascii2bn(bn,a) +BIGNUM **bn; +char *a; + { + BIGNUM *ret=NULL; + BN_ULONG l=0; + int neg=0,h,m,i,j,k,c; + int num; + + if ((a == NULL) || (*a == '\0')) return(0); + + if (*a == '-') { neg=1; a++; } + + for (i=0; isxdigit(a[i]); i++) + ; + + num=i+neg; + if (bn == NULL) return(num); + + /* a is the start of the hex digets, and it is 'i' long */ + if (*bn == NULL) + { + if ((ret=BN_new()) == NULL) return(0); + } + else + { + ret= *bn; + BN_zero(ret); + } + + /* i is the number of hex digests; */ + if (bn_expand(ret,i*4) == NULL) goto err; + + j=i; /* least significate 'hex' */ + m=0; + h=0; + while (j > 0) + { + m=((BN_BYTES*2) <= j)?(BN_BYTES*2):j; + l=0; + for (;;) + { + c=a[j-m]; + if ((c >= '0') && (c <= '9')) k=c-'0'; + else if ((c >= 'a') && (c <= 'f')) k=c-'a'+10; + else if ((c >= 'A') && (c <= 'F')) k=c-'A'+10; + else k=0; /* paranoia */ + l=(l<<4)|k; + + if (--m <= 0) + { + ret->d[h++]=l; + break; + } + } + j-=(BN_BYTES*2); + } + ret->top=h; + bn_fix_top(ret); + ret->neg=neg; + + *bn=ret; + return(num); +err: + if (*bn == NULL) BN_free(ret); + return(0); + } + +#ifndef NO_BIO + +#ifndef WIN16 +int BN_print_fp(fp, a) +FILE *fp; +BIGNUM *a; + { + BIO *b; + int ret; + + if ((b=BIO_new(BIO_s_file())) == NULL) + return(0); + BIO_set_fp(b,fp,BIO_NOCLOSE); + ret=BN_print(b,a); + BIO_free(b); + return(ret); + } +#endif + +int BN_print(bp, a) +BIO *bp; +BIGNUM *a; + { + int i,j,v,z=0; + int ret=0; + + if ((a->neg) && (BIO_write(bp,"-",1) != 1)) goto end; + if ((a->top == 0) && (BIO_write(bp,"0",1) != 1)) goto end; + for (i=a->top-1; i >=0; i--) + { + for (j=BN_BITS2-4; j >= 0; j-=4) + { + /* strip leading zeros */ + v=((int)(a->d[i]>>(long)j))&0x0f; + if (z || (v != 0)) + { + if (BIO_write(bp,&(Hex[v]),1) != 1) + goto end; + z=1; + } + } + } + ret=1; +end: + return(ret); + } + +#endif diff --git a/crypto/bn/bn_rand.c b/crypto/bn/bn_rand.c new file mode 100644 index 0000000000..e3530a5bf2 --- /dev/null +++ b/crypto/bn/bn_rand.c @@ -0,0 +1,121 @@ +/* crypto/bn/bn_rand.c */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include <time.h> +#include "cryptlib.h" +#include "bn_lcl.h" +#include "rand.h" + +int BN_rand(rnd, bits, top, bottom) +BIGNUM *rnd; +int bits; +int top; +int bottom; + { + unsigned char *buf=NULL; + int ret=0,bit,bytes,mask; + time_t tim; + + bytes=(bits+7)/8; + bit=(bits-1)%8; + mask=0xff<<bit; + + buf=(unsigned char *)Malloc(bytes); + if (buf == NULL) + { + BNerr(BN_F_BN_RAND,ERR_R_MALLOC_FAILURE); + goto err; + } + + /* make a random number and set the top and bottom bits */ + time(&tim); + RAND_seed((unsigned char *)&tim,sizeof(tim)); + + RAND_bytes(buf,(int)bytes); + if (top) + { + if (bit == 0) + { + buf[0]=1; + buf[1]|=0x80; + } + else + { + buf[0]|=(3<<(bit-1)); + buf[0]&= ~(mask<<1); + } + } + else + { + buf[0]|=(1<<bit); + buf[0]&= ~(mask<<1); + } + if (bottom) /* set bottom bits to whatever odd is */ + buf[bytes-1]|=1; + if (!BN_bin2bn(buf,bytes,rnd)) goto err; + ret=1; +err: + if (buf != NULL) + { + memset(buf,0,bytes); + Free(buf); + } + return(ret); + } + diff --git a/crypto/bn/bn_recp.c b/crypto/bn/bn_recp.c new file mode 100644 index 0000000000..fd9ca4dbf6 --- /dev/null +++ b/crypto/bn/bn_recp.c @@ -0,0 +1,125 @@ +/* crypto/bn/bn_recp.c */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include "cryptlib.h" +#include "bn_lcl.h" + +int BN_mod_mul_reciprocal(r, x, y, m, i, nb, ctx) +BIGNUM *r; +BIGNUM *x; +BIGNUM *y; +BIGNUM *m; +BIGNUM *i; +int nb; +BN_CTX *ctx; + { + int ret=0,j; + BIGNUM *a,*b,*c,*d; + + a=ctx->bn[ctx->tos++]; + b=ctx->bn[ctx->tos++]; + c=ctx->bn[ctx->tos++]; + d=ctx->bn[ctx->tos++]; + + if (x == y) + { if (!BN_sqr(a,x,ctx)) goto err; } + else + { if (!BN_mul(a,x,y)) goto err; } + if (!BN_rshift(d,a,nb)) goto err; + if (!BN_mul(b,d,i)) goto err; + if (!BN_rshift(c,b,nb)) goto err; + if (!BN_mul(b,m,c)) goto err; + if (!BN_sub(r,a,b)) goto err; + j=0; + while (BN_cmp(r,m) >= 0) + { + if (j++ > 2) + { + BNerr(BN_F_BN_MOD_MUL_RECIPROCAL,BN_R_BAD_RECIPROCAL); + goto err; + } + if (!BN_sub(r,r,m)) goto err; + } + + ret=1; +err: + ctx->tos-=4; + return(ret); + } + +int BN_reciprocal(r, m,ctx) +BIGNUM *r; +BIGNUM *m; +BN_CTX *ctx; + { + int nm,ret= -1; + BIGNUM *t; + + t=ctx->bn[ctx->tos++]; + + nm=BN_num_bits(m); + if (!BN_lshift(t,BN_value_one(),nm*2)) goto err; + + if (!BN_div(r,NULL,t,m,ctx)) goto err; + ret=nm; +err: + ctx->tos--; + return(ret); + } + diff --git a/crypto/bn/bn_shift.c b/crypto/bn/bn_shift.c new file mode 100644 index 0000000000..d711887373 --- /dev/null +++ b/crypto/bn/bn_shift.c @@ -0,0 +1,210 @@ +/* crypto/bn/bn_shift.c */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include "cryptlib.h" +#include "bn_lcl.h" + +int BN_lshift1(r, a) +BIGNUM *r; +BIGNUM *a; + { + register BN_ULONG *ap,*rp,t,c; + int i; + + if (r != a) + { + r->neg=a->neg; + if (bn_expand(r,(a->top+1)*BN_BITS2) == NULL) return(0); + r->top=a->top; + } + else + { + if (bn_expand(r,(a->top+1)*BN_BITS2) == NULL) return(0); + } + ap=a->d; + rp=r->d; + c=0; + for (i=0; i<a->top; i++) + { + t= *(ap++); + *(rp++)=((t<<1)|c)&BN_MASK2; + c=(t & BN_TBIT)?1:0; + } + if (c) + { + *rp=1; + r->top++; + } + return(1); + } + +int BN_rshift1(r, a) +BIGNUM *r; +BIGNUM *a; + { + BN_ULONG *ap,*rp,t,c; + int i; + + if (BN_is_zero(a)) + { + BN_zero(r); + return(1); + } + if (a != r) + { + if (bn_expand(r,a->top*BN_BITS2) == NULL) return(0); + r->top=a->top; + r->neg=a->neg; + } + ap=a->d; + rp=r->d; + c=0; + for (i=a->top-1; i>=0; i--) + { + t=ap[i]; + rp[i]=((t>>1)&BN_MASK2)|c; + c=(t&1)?BN_TBIT:0; + } + bn_fix_top(r); + return(1); + } + +int BN_lshift(r, a, n) +BIGNUM *r; +BIGNUM *a; +int n; + { + int i,nw,lb,rb; + BN_ULONG *t,*f; + BN_ULONG l; + + r->neg=a->neg; + if (bn_expand(r,(a->top*BN_BITS2)+n) == NULL) return(0); + nw=n/BN_BITS2; + lb=n%BN_BITS2; + rb=BN_BITS2-lb; + f=a->d; + t=r->d; + t[a->top+nw]=0; + if (lb == 0) + for (i=a->top-1; i>=0; i--) + t[nw+i]=f[i]; + else + for (i=a->top-1; i>=0; i--) + { + l=f[i]; + t[nw+i+1]|=(l>>rb)&BN_MASK2; + t[nw+i]=(l<<lb)&BN_MASK2; + } + memset(t,0,nw*sizeof(t[0])); +/* for (i=0; i<nw; i++) + t[i]=0;*/ + r->top=a->top+nw+1; + bn_fix_top(r); + return(1); + } + +int BN_rshift(r, a, n) +BIGNUM *r; +BIGNUM *a; +int n; + { + int i,j,nw,lb,rb; + BN_ULONG *t,*f; + BN_ULONG l,tmp; + + nw=n/BN_BITS2; + rb=n%BN_BITS2; + lb=BN_BITS2-rb; + if (nw > a->top) + { + BN_zero(r); + return(1); + } + if (r != a) + { + r->neg=a->neg; + if (bn_expand(r,(a->top-nw+1)*BN_BITS2) == NULL) return(0); + } + + f= &(a->d[nw]); + t=r->d; + j=a->top-nw; + r->top=j; + + if (rb == 0) + { + for (i=j+1; i > 0; i--) + *(t++)= *(f++); + } + else + { + l= *(f++); + for (i=1; i<j; i++) + { + tmp =(l>>rb)&BN_MASK2; + l= *(f++); + *(t++) =(tmp|(l<<lb))&BN_MASK2; + } + *(t++) =(l>>rb)&BN_MASK2; + } + *t=0; + bn_fix_top(r); + return(1); + } diff --git a/crypto/bn/bn_sqr.c b/crypto/bn/bn_sqr.c new file mode 100644 index 0000000000..4c3f0a0986 --- /dev/null +++ b/crypto/bn/bn_sqr.c @@ -0,0 +1,161 @@ +/* crypto/bn/bn_sqr.c */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include "cryptlib.h" +#include "bn_lcl.h" + +/* r must not be a */ +/* I've just gone over this and it is now %20 faster on x86 - eay - 27 Jun 96 */ +int BN_sqr(r, a, ctx) +BIGNUM *r; +BIGNUM *a; +BN_CTX *ctx; + { + int i,j,max,al; + BIGNUM *tmp; + BN_ULONG *ap,*rp,c; + + tmp=ctx->bn[ctx->tos]; + + al=a->top; + if (al == 0) + { + r->top=0; + return(1); + } + + max=(al*2); + if (bn_expand(r,max*BN_BITS2) == NULL) return(0); + if (bn_expand(tmp,max*BN_BITS2) == NULL) return(0); + + r->neg=0; + + ap=a->d; + rp=r->d; + rp[0]=rp[max-1]=0; + rp++; + j=al; + + if (--j > 0) + { + ap++; + rp[j]=bn_mul_word(rp,ap,j,ap[-1]); + rp+=2; + } + + for (i=2; i<al; i++) + { + j--; + ap++; + rp[j]=bn_mul_add_word(rp,ap,j,ap[-1]); + rp+=2; + } + + /* inlined shift, 2 words at once */ + j=max; + rp=r->d; + c=0; + for (i=0; i<j; i++) + { + BN_ULONG t; + + t= *rp; + *(rp++)=((t<<1)|c)&BN_MASK2; + c=(t & BN_TBIT)?1:0; + +#if 0 + t= *rp; + *(rp++)=((t<<1)|c)&BN_MASK2; + c=(t & BN_TBIT)?1:0; +#endif + } + /* there will not be a carry */ + + bn_sqr_words(tmp->d,a->d,al); + + /* inlined add */ + ap=tmp->d; + rp=r->d; + c=0; + j=max; + for (i=0; i<j; i++) + { + BN_ULONG t1,t2; + + t1= *(ap++); + t2= *rp; + if (c) + { + c=(t2 >= ((~t1)&BN_MASK2)); + t2=(t1+t2+1)&BN_MASK2; + } + else + { + t2=(t1+t2)&BN_MASK2; + c=(t2<t1); + } + *(rp++)=t2; + } + /* there will be no carry */ + + r->top=max; + if (r->d[max-1] == 0) r->top--; + return(1); + } + diff --git a/crypto/bn/bn_sub.c b/crypto/bn/bn_sub.c new file mode 100644 index 0000000000..b0febc3421 --- /dev/null +++ b/crypto/bn/bn_sub.c @@ -0,0 +1,176 @@ +/* crypto/bn/bn_sub.c */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include "cryptlib.h" +#include "bn_lcl.h" + +/* unsigned subtraction of b from a, a must be larger than b. */ +void bn_qsub(r, a, b) +BIGNUM *r; +BIGNUM *a; +BIGNUM *b; + { + int max,min; + register BN_ULONG t1,t2,*ap,*bp,*rp; + int i,carry; +#if defined(IRIX_CC_BUG) && !defined(LINT) + int dummy; +#endif + + max=a->top; + min=b->top; + ap=a->d; + bp=b->d; + rp=r->d; + + carry=0; + for (i=0; i<min; i++) + { + t1= *(ap++); + t2= *(bp++); + if (carry) + { + carry=(t1 <= t2); + t1=(t1-t2-1); + } + else + { + carry=(t1 < t2); + t1=(t1-t2); + } +#if defined(IRIX_CC_BUG) && !defined(LINT) + dummy=t1; +#endif + *(rp++)=t1&BN_MASK2; + } + if (carry) /* subtracted */ + { + while (i < max) + { + i++; + t1= *(ap++); + t2=(t1-1)&BN_MASK2; + *(rp++)=t2; + if (t1 > t2) break; + } + } + memcpy(rp,ap,sizeof(*rp)*(max-i)); +/* for (; i<max; i++) + *(rp++)= *(ap++);*/ + + r->top=max; + bn_fix_top(r); + } + +int BN_sub(r, a, b) +BIGNUM *r; +BIGNUM *a; +BIGNUM *b; + { + int max,i; + int add=0,neg=0; + BIGNUM *tmp; + + /* a - b a-b + * a - -b a+b + * -a - b -(a+b) + * -a - -b b-a + */ + if (a->neg) + { + if (b->neg) + { tmp=a; a=b; b=tmp; } + else + { add=1; neg=1; } + } + else + { + if (b->neg) { add=1; neg=0; } + } + + if (add) + { + i=(a->top > b->top); + if (bn_expand(r,(((i)?a->top:b->top)+1)*BN_BITS2) == NULL) + return(0); + if (i) + bn_qadd(r,a,b); + else + bn_qadd(r,b,a); + r->neg=neg; + return(1); + } + + /* We are actually doing a - b :-) */ + + max=(a->top > b->top)?a->top:b->top; + if (bn_expand(r,max*BN_BITS2) == NULL) return(0); + if (BN_ucmp(a,b) < 0) + { + bn_qsub(r,b,a); + r->neg=1; + } + else + { + bn_qsub(r,a,b); + r->neg=0; + } + return(1); + } + diff --git a/crypto/bn/bn_word.c b/crypto/bn/bn_word.c new file mode 100644 index 0000000000..b61ddd95ce --- /dev/null +++ b/crypto/bn/bn_word.c @@ -0,0 +1,155 @@ +/* crypto/bn/bn_word.c */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include "cryptlib.h" +#include "bn_lcl.h" + +BN_ULONG BN_mod_word(a, w) +BIGNUM *a; +unsigned long w; + { +#ifndef BN_LLONG + BN_ULONG ret=0; +#else + BN_ULLONG ret=0; +#endif + int i; + + for (i=a->top-1; i>=0; i--) + { +#ifndef BN_LLONG + ret=((ret<<BN_BITS4)|((a->d[i]>>BN_BITS4)&BN_MASK2l))%(int)w; + ret=((ret<<BN_BITS4)|(a->d[i]&BN_MASK2l))%(int)w; +#else + ret=(BN_ULLONG)(((ret<<(BN_ULLONG)BN_BITS2)|a->d[i])% + (BN_ULLONG)w); +#endif + } + return((BN_ULONG)ret); + } + +BN_ULONG BN_div_word(a, w) +BIGNUM *a; +unsigned long w; + { + BN_ULONG ret; + int i; + + if (a->top == 0) return(0); + ret=0; + for (i=a->top-1; i>=0; i--) + { +#ifndef BN_LLONG + ret=((ret<<BN_BITS4)|((a->d[i]>>BN_BITS4)&BN_MASK2l))%(int)w; + ret=((ret<<BN_BITS4)|(a->d[i]&BN_MASK2l))%(int)w; +#else + BN_ULLONG ll; + + ll=((BN_ULLONG)ret<<(BN_ULONG)BN_BITS2)|a->d[i]; + a->d[i]=(BN_ULONG)(ll/w); + ret=(BN_ULONG)(ll%w); +#endif + } + if (a->d[a->top-1] == 0) + a->top--; + return(ret); + } + +int BN_add_word(a, w) +BIGNUM *a; +unsigned long w; + { + BN_ULONG l; + int i; + + if (bn_expand(a,a->top*BN_BITS2+1) == NULL) return(0); + i=0; + for (;;) + { + l=(a->d[i]+(BN_ULONG)w)&BN_MASK2; + a->d[i]=l; + if (w > l) + w=1; + else + break; + i++; + } + if (i >= a->top) + a->top++; + return(1); + } + +#ifdef undef +BN_ULONG *BN_mod_inverse_word(a) +BN_ULONG a; + { + BN_ULONG A,B,X,Y,M,D,R,RET,T; + int sign,hight=1; + + X=0; + Y=1; + A=0; + B=a; + sign=1; + + while (B != 0) + { + +#endif + diff --git a/crypto/bn/bnspeed.c b/crypto/bn/bnspeed.c new file mode 100644 index 0000000000..3b83a26dea --- /dev/null +++ b/crypto/bn/bnspeed.c @@ -0,0 +1,240 @@ +/* crypto/bn/bnspeed.c */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* most of this code has been pilfered from my libdes speed.c program */ + +#undef PROG +#define PROG bnspeed_main + +#include <stdio.h> +#include <stdlib.h> +#include <signal.h> +#include <string.h> +#include "crypto.h" +#include "err.h" + +#ifndef MSDOS +#define TIMES +#endif + +#ifndef VMS +#ifndef _IRIX +#include <time.h> +#endif +#ifdef TIMES +#include <sys/types.h> +#include <sys/times.h> +#endif +#else /* VMS */ +#include <types.h> +struct tms { + time_t tms_utime; + time_t tms_stime; + time_t tms_uchild; /* I dunno... */ + time_t tms_uchildsys; /* so these names are a guess :-) */ + } +#endif +#ifndef TIMES +#include <sys/timeb.h> +#endif + +#ifdef sun +#include <limits.h> +#include <sys/param.h> +#endif + +#include "bn.h" +#include "x509.h" + +/* The following if from times(3) man page. It may need to be changed */ +#ifndef HZ +# ifndef CLK_TCK +# ifndef _BSD_CLK_TCK_ /* FreeBSD hack */ +# ifndef VMS +# define HZ 100.0 +# else /* VMS */ +# define HZ 100.0 +# endif +# else /* _BSD_CLK_TCK_ */ +# define HZ ((double)_BSD_CLK_TCK_) +# endif +# else /* CLK_TCK */ +# define HZ ((double)CLK_TCK) +# endif +#endif + +#undef BUFSIZE +#define BUFSIZE ((long)1024*8) +int run=0; + +#ifndef NOPROTO +static double Time_F(int s); +#else +static double Time_F(); +#endif + +#define START 0 +#define STOP 1 + +static double Time_F(s) +int s; + { + double ret; +#ifdef TIMES + static struct tms tstart,tend; + + if (s == START) + { + times(&tstart); + return(0); + } + else + { + times(&tend); + ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ; + return((ret < 1e-3)?1e-3:ret); + } +#else /* !times() */ + static struct timeb tstart,tend; + long i; + + if (s == START) + { + ftime(&tstart); + return(0); + } + else + { + ftime(&tend); + i=(long)tend.millitm-(long)tstart.millitm; + ret=((double)(tend.time-tstart.time))+((double)i)/1000.0; + return((ret < 0.001)?0.001:ret); + } +#endif + } + +#define NUM_SIZES 5 +/*static int sizes[NUM_SIZES]={256,512,1024,2048};*/ +static int sizes[NUM_SIZES]={59,179,299,419,539}; + +void do_mul(BIGNUM *r,BIGNUM *a,BIGNUM *b,BN_CTX *ctx); + +int main(argc,argv) +int argc; +char **argv; + { + BN_CTX *ctx; + BIGNUM *a,*b,*c,*r; + + ctx=BN_CTX_new(); + a=BN_new(); + b=BN_new(); + c=BN_new(); + r=BN_new(); + + do_mul(a,b,c,ctx); + } + +void do_mul(r,a,b,ctx) +BIGNUM *r; +BIGNUM *a; +BIGNUM *b; +BN_CTX *ctx; + { + int i,j,k; + double tm; + + for (i=0; i<NUM_SIZES; i++) + { + BN_rand(a,sizes[i],1,0); + for (j=i; j<NUM_SIZES; j++) + { + BN_rand(b,sizes[j],1,0); + Time_F(START); + for (k=0; k<100000; k++) + BN_mul(r,b,a); + tm=Time_F(STOP); + printf("mul %3d x %3d -> %7.4f\n",sizes[i],sizes[j],tm/10.0); + } + } + + for (i=0; i<NUM_SIZES; i++) + { + BN_rand(a,sizes[i],1,0); + Time_F(START); + for (k=0; k<100000; k++) + BN_sqr(r,a,ctx); + tm=Time_F(STOP); + printf("sqr %3d x %3d -> %7.4f\n",sizes[i],sizes[i],tm/10.0); + } + + for (i=0; i<NUM_SIZES; i++) + { + BN_rand(a,sizes[i],1,0); + for (j=i; j<NUM_SIZES; j++) + { + BN_rand(b,sizes[j],1,0); + Time_F(START); + for (k=0; k<100000; k++) + BN_div(r, NULL, b, a,ctx); + tm=Time_F(STOP); + printf("div %3d / %3d -> %7.4f\n",sizes[j],sizes[i],tm/10.0); + } + } + } + diff --git a/crypto/bn/bntest.c b/crypto/bn/bntest.c new file mode 100644 index 0000000000..7a2f0b8d6d --- /dev/null +++ b/crypto/bn/bntest.c @@ -0,0 +1,775 @@ +/* crypto/bn/bntest.c */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#ifdef WIN16 +#define APPS_WIN16 +#endif +#include "bio.h" +#include "bn.h" +#include "rand.h" +#include "x509.h" +#include "err.h" + +#ifndef NOPROTO +int test_add (BIO *bp); +int test_sub (BIO *bp); +int test_lshift1 (BIO *bp); +int test_lshift (BIO *bp); +int test_rshift1 (BIO *bp); +int test_rshift (BIO *bp); +int test_div (BIO *bp,BN_CTX *ctx); +int test_mul (BIO *bp); +int test_sqr (BIO *bp,BN_CTX *ctx); +int test_mont (BIO *bp,BN_CTX *ctx); +int test_mod (BIO *bp,BN_CTX *ctx); +int test_mod_mul (BIO *bp,BN_CTX *ctx); +int test_mod_exp (BIO *bp,BN_CTX *ctx); +int rand_neg(void); +#else +int test_add (); +int test_sub (); +int test_lshift1 (); +int test_lshift (); +int test_rshift1 (); +int test_rshift (); +int test_div (); +int test_mul (); +int test_sqr (); +int test_mont (); +int test_mod (); +int test_mod_mul (); +int test_mod_exp (); +int rand_neg(); +#endif + +static int results=0; + +#ifdef WIN16 +#define APPS_WIN16 +#include "../bio/bss_file.c" +#endif + +int main(argc,argv) +int argc; +char *argv[]; + { + BN_CTX *ctx; + BIO *out; + char *outfile=NULL; + + srand((unsigned int)time(NULL)); + + argc--; + argv++; + while (argc >= 1) + { + if (strcmp(*argv,"-results") == 0) + results=1; + else if (strcmp(*argv,"-out") == 0) + { + if (--argc < 1) break; + outfile= *(++argv); + } + argc--; + argv++; + } + + + ctx=BN_CTX_new(); + if (ctx == NULL) exit(1); + + out=BIO_new(BIO_s_file()); + if (out == NULL) exit(1); + if (outfile == NULL) + { + BIO_set_fp(out,stdout,BIO_NOCLOSE); + } + else + { + if (!BIO_write_filename(out,outfile)) + { + perror(outfile); + exit(1); + } + } + + if (!results) + BIO_puts(out,"obase=16\nibase=16\n"); + + fprintf(stderr,"test BN_add\n"); + if (!test_add(out)) goto err; + fflush(stdout); + + fprintf(stderr,"test BN_sub\n"); + if (!test_sub(out)) goto err; + fflush(stdout); + + fprintf(stderr,"test BN_lshift1\n"); + if (!test_lshift1(out)) goto err; + fflush(stdout); + + fprintf(stderr,"test BN_lshift\n"); + if (!test_lshift(out)) goto err; + fflush(stdout); + + fprintf(stderr,"test BN_rshift1\n"); + if (!test_rshift1(out)) goto err; + fflush(stdout); + + fprintf(stderr,"test BN_rshift\n"); + if (!test_rshift(out)) goto err; + fflush(stdout); + + fprintf(stderr,"test BN_div\n"); + if (!test_div(out,ctx)) goto err; + fflush(stdout); + + fprintf(stderr,"test BN_mod\n"); + if (!test_mod(out,ctx)) goto err; + fflush(stdout); + + fprintf(stderr,"test BN_mul\n"); + if (!test_mul(out)) goto err; + fflush(stdout); + + fprintf(stderr,"test BN_sqr\n"); + if (!test_sqr(out,ctx)) goto err; + fflush(stdout); + + fprintf(stderr,"test BN_mod_mul\n"); + if (!test_mod_mul(out,ctx)) goto err; + fflush(stdout); + +/* + fprintf(stderr,"test BN_mont\n"); + if (!test_mont(out,ctx)) goto err; + fflush(stdout); +*/ + fprintf(stderr,"test BN_mod_exp\n"); + if (!test_mod_exp(out,ctx)) goto err; + fflush(stdout); + +/**/ + exit(0); +err: + ERR_load_crypto_strings(); + ERR_print_errors(out); + exit(1); + return(1); + } + +int test_add(bp) +BIO *bp; + { + BIGNUM *a,*b,*c; + int i; + int j; + + a=BN_new(); + b=BN_new(); + c=BN_new(); + + BN_rand(a,512,0,0); + for (i=0; i<100; i++) + { + BN_rand(b,450+i,0,0); + a->neg=rand_neg(); + b->neg=rand_neg(); + if (bp == NULL) + for (j=0; j<10000; j++) + BN_add(c,a,b); + BN_add(c,a,b); + if (bp != NULL) + { + if (!results) + { + BN_print(bp,a); + BIO_puts(bp," + "); + BN_print(bp,b); + BIO_puts(bp," - "); + } + BN_print(bp,c); + BIO_puts(bp,"\n"); + } + } + BN_free(a); + BN_free(b); + BN_free(c); + return(1); + } + +int test_sub(bp) +BIO *bp; + { + BIGNUM *a,*b,*c; + int i; + int j; + + a=BN_new(); + b=BN_new(); + c=BN_new(); + + BN_rand(a,512,0,0); + for (i=0; i<100; i++) + { + BN_rand(b,400+i,0,0); + a->neg=rand_neg(); + b->neg=rand_neg(); + if (bp == NULL) + for (j=0; j<10000; j++) + BN_sub(c,a,b); + BN_sub(c,a,b); + if (bp != NULL) + { + if (!results) + { + BN_print(bp,a); + BIO_puts(bp," - "); + BN_print(bp,b); + BIO_puts(bp," - "); + } + BN_print(bp,c); + BIO_puts(bp,"\n"); + } + } + BN_free(a); + BN_free(b); + BN_free(c); + return(1); + } + +int test_div(bp,ctx) +BIO *bp; +BN_CTX *ctx; + { + BIGNUM *a,*b,*c,*d; + int i; + int j; + + a=BN_new(); + b=BN_new(); + c=BN_new(); + d=BN_new(); + + BN_rand(a,400,0,0); + for (i=0; i<100; i++) + { + BN_rand(b,50+i,0,0); + a->neg=rand_neg(); + b->neg=rand_neg(); + if (bp == NULL) + for (j=0; j<100; j++) + BN_div(d,c,a,b,ctx); + BN_div(d,c,a,b,ctx); + if (bp != NULL) + { + if (!results) + { + BN_print(bp,a); + BIO_puts(bp," / "); + BN_print(bp,b); + BIO_puts(bp," - "); + } + BN_print(bp,d); + BIO_puts(bp,"\n"); + + if (!results) + { + BN_print(bp,a); + BIO_puts(bp," % "); + BN_print(bp,b); + BIO_puts(bp," - "); + } + BN_print(bp,c); + BIO_puts(bp,"\n"); + } + } + BN_free(a); + BN_free(b); + BN_free(c); + BN_free(d); + return(1); + } + +int test_mul(bp) +BIO *bp; + { + BIGNUM *a,*b,*c; + int i; + int j; + + a=BN_new(); + b=BN_new(); + c=BN_new(); + + BN_rand(a,200,0,0); + for (i=0; i<100; i++) + { + BN_rand(b,250+i,0,0); + a->neg=rand_neg(); + b->neg=rand_neg(); + if (bp == NULL) + for (j=0; j<100; j++) + BN_mul(c,a,b); + BN_mul(c,a,b); + if (bp != NULL) + { + if (!results) + { + BN_print(bp,a); + BIO_puts(bp," * "); + BN_print(bp,b); + BIO_puts(bp," - "); + } + BN_print(bp,c); + BIO_puts(bp,"\n"); + } + } + BN_free(a); + BN_free(b); + BN_free(c); + return(1); + } + +int test_sqr(bp,ctx) +BIO *bp; +BN_CTX *ctx; + { + BIGNUM *a,*c; + int i; + int j; + + a=BN_new(); + c=BN_new(); + + for (i=0; i<40; i++) + { + BN_rand(a,40+i*10,0,0); + a->neg=rand_neg(); + if (bp == NULL) + for (j=0; j<100; j++) + BN_sqr(c,a,ctx); + BN_sqr(c,a,ctx); + if (bp != NULL) + { + if (!results) + { + BN_print(bp,a); + BIO_puts(bp," * "); + BN_print(bp,a); + BIO_puts(bp," - "); + } + BN_print(bp,c); + BIO_puts(bp,"\n"); + } + } + BN_free(a); + BN_free(c); + return(1); + } + +int test_mont(bp,ctx) +BIO *bp; +BN_CTX *ctx; + { + BIGNUM *a,*b,*c,*A,*B; + BIGNUM *n; + int i; + int j; + BN_MONT_CTX *mont; + + a=BN_new(); + b=BN_new(); + c=BN_new(); + A=BN_new(); + B=BN_new(); + n=BN_new(); + + mont=BN_MONT_CTX_new(); + + BN_rand(a,100,0,0); /**/ + BN_rand(b,100,0,0); /**/ + for (i=0; i<10; i++) + { + BN_rand(n,(100%BN_BITS2+1)*BN_BITS2*i*BN_BITS2,0,1); /**/ + BN_MONT_CTX_set(mont,n,ctx); + + BN_to_montgomery(A,a,mont,ctx); + BN_to_montgomery(B,b,mont,ctx); + + if (bp == NULL) + for (j=0; j<100; j++) + BN_mod_mul_montgomery(c,A,B,mont,ctx);/**/ + BN_mod_mul_montgomery(c,A,B,mont,ctx);/**/ + BN_from_montgomery(A,c,mont,ctx);/**/ + if (bp != NULL) + { + if (!results) + { +#ifdef undef +fprintf(stderr,"%d * %d %% %d\n", +BN_num_bits(a), +BN_num_bits(b), +BN_num_bits(mont->N)); +#endif + BN_print(bp,a); + BIO_puts(bp," * "); + BN_print(bp,b); + BIO_puts(bp," % "); + BN_print(bp,mont->N); + BIO_puts(bp," - "); + } + BN_print(bp,A); + BIO_puts(bp,"\n"); + } + } + BN_MONT_CTX_free(mont); + BN_free(a); + BN_free(b); + BN_free(c); + return(1); + } + +int test_mod(bp,ctx) +BIO *bp; +BN_CTX *ctx; + { + BIGNUM *a,*b,*c; + int i; + int j; + + a=BN_new(); + b=BN_new(); + c=BN_new(); + + BN_rand(a,1024,0,0); /**/ + for (i=0; i<20; i++) + { + BN_rand(b,450+i*10,0,0); /**/ + a->neg=rand_neg(); + b->neg=rand_neg(); + if (bp == NULL) + for (j=0; j<100; j++) + BN_mod(c,a,b,ctx);/**/ + BN_mod(c,a,b,ctx);/**/ + if (bp != NULL) + { + if (!results) + { + BN_print(bp,a); + BIO_puts(bp," % "); + BN_print(bp,b); + BIO_puts(bp," - "); + } + BN_print(bp,c); + BIO_puts(bp,"\n"); + } + } + BN_free(a); + BN_free(b); + BN_free(c); + return(1); + } + +int test_mod_mul(bp,ctx) +BIO *bp; +BN_CTX *ctx; + { + BIGNUM *a,*b,*c,*d,*e; + int i; + + a=BN_new(); + b=BN_new(); + c=BN_new(); + d=BN_new(); + e=BN_new(); + + BN_rand(c,1024,0,0); /**/ + for (i=0; i<10; i++) + { + BN_rand(a,475+i*10,0,0); /**/ + BN_rand(b,425+i*10,0,0); /**/ + a->neg=rand_neg(); + b->neg=rand_neg(); + /* if (bp == NULL) + for (j=0; j<100; j++) + BN_mod_mul(d,a,b,c,ctx);*/ /**/ + + if (!BN_mod_mul(e,a,b,c,ctx)) + { + unsigned long l; + + while ((l=ERR_get_error())) + fprintf(stderr,"ERROR:%s\n", + ERR_error_string(l,NULL)); + exit(1); + } + if (bp != NULL) + { + if (!results) + { + BN_print(bp,a); + BIO_puts(bp," * "); + BN_print(bp,b); + BIO_puts(bp," % "); + BN_print(bp,c); + BIO_puts(bp," - "); + } + BN_print(bp,e); + BIO_puts(bp,"\n"); + } + } + BN_free(a); + BN_free(b); + BN_free(c); + BN_free(d); + BN_free(e); + return(1); + } + +int test_mod_exp(bp,ctx) +BIO *bp; +BN_CTX *ctx; + { + BIGNUM *a,*b,*c,*d,*e; + int i; + + a=BN_new(); + b=BN_new(); + c=BN_new(); + d=BN_new(); + e=BN_new(); + + BN_rand(c,30,0,1); /* must be odd for montgomery */ + for (i=0; i<6; i++) + { + BN_rand(a,20+i*5,0,0); /**/ + BN_rand(b,2+i,0,0); /**/ + + if (!BN_mod_exp(d,a,b,c,ctx)) + return(00); + + if (bp != NULL) + { + if (!results) + { + BN_print(bp,a); + BIO_puts(bp," ^ "); + BN_print(bp,b); + BIO_puts(bp," % "); + BN_print(bp,c); + BIO_puts(bp," - "); + } + BN_print(bp,d); + BIO_puts(bp,"\n"); + } + } + BN_free(a); + BN_free(b); + BN_free(c); + BN_free(d); + BN_free(e); + return(1); + } + +int test_lshift(bp) +BIO *bp; + { + BIGNUM *a,*b,*c; + int i; + + a=BN_new(); + b=BN_new(); + c=BN_new(); + BN_one(c); + + BN_rand(a,200,0,0); /**/ + a->neg=rand_neg(); + for (i=0; i<70; i++) + { + BN_lshift(b,a,i+1); + BN_add(c,c,c); + if (bp != NULL) + { + if (!results) + { + BN_print(bp,a); + BIO_puts(bp," * "); + BN_print(bp,c); + BIO_puts(bp," - "); + } + BN_print(bp,b); + BIO_puts(bp,"\n"); + } + } + BN_free(a); + BN_free(b); + BN_free(c); + return(1); + } + +int test_lshift1(bp) +BIO *bp; + { + BIGNUM *a,*b; + int i; + + a=BN_new(); + b=BN_new(); + + BN_rand(a,200,0,0); /**/ + a->neg=rand_neg(); + for (i=0; i<70; i++) + { + BN_lshift1(b,a); + if (bp != NULL) + { + if (!results) + { + BN_print(bp,a); + BIO_puts(bp," * 2"); + BIO_puts(bp," - "); + } + BN_print(bp,b); + BIO_puts(bp,"\n"); + } + BN_copy(a,b); + } + BN_free(a); + BN_free(b); + return(1); + } + +int test_rshift(bp) +BIO *bp; + { + BIGNUM *a,*b,*c; + int i; + + a=BN_new(); + b=BN_new(); + c=BN_new(); + BN_one(c); + + BN_rand(a,200,0,0); /**/ + a->neg=rand_neg(); + for (i=0; i<70; i++) + { + BN_rshift(b,a,i+1); + BN_add(c,c,c); + if (bp != NULL) + { + if (!results) + { + BN_print(bp,a); + BIO_puts(bp," / "); + BN_print(bp,c); + BIO_puts(bp," - "); + } + BN_print(bp,b); + BIO_puts(bp,"\n"); + } + } + BN_free(a); + BN_free(b); + BN_free(c); + return(1); + } + +int test_rshift1(bp) +BIO *bp; + { + BIGNUM *a,*b; + int i; + + a=BN_new(); + b=BN_new(); + + BN_rand(a,200,0,0); /**/ + a->neg=rand_neg(); + for (i=0; i<70; i++) + { + BN_rshift1(b,a); + if (bp != NULL) + { + if (!results) + { + BN_print(bp,a); + BIO_puts(bp," / 2"); + BIO_puts(bp," - "); + } + BN_print(bp,b); + BIO_puts(bp,"\n"); + } + BN_copy(a,b); + } + BN_free(a); + BN_free(b); + return(1); + } + +int rand_neg() + { + static unsigned int neg=0; + static int sign[8]={0,0,0,1,1,0,1,1}; + + return(sign[(neg++)%8]); + } diff --git a/crypto/bn/exptest.c b/crypto/bn/exptest.c new file mode 100644 index 0000000000..4880df1116 --- /dev/null +++ b/crypto/bn/exptest.c @@ -0,0 +1,148 @@ +/* crypto/bn/exptest.c */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "bio.h" +#include "bn.h" +#include "rand.h" +#include "err.h" + +#define NUM_BITS (BN_BITS*2) + +int main(argc,argv) +int argc; +char *argv[]; + { + BN_CTX *ctx; + BIO *out=NULL; + int i,ret; + unsigned char c; + BIGNUM *r_mont,*r_recp,*a,*b,*m; + + ctx=BN_CTX_new(); + if (ctx == NULL) exit(1); + r_mont=BN_new(); + r_recp=BN_new(); + a=BN_new(); + b=BN_new(); + m=BN_new(); + if ( (r_mont == NULL) || (r_recp == NULL) || + (a == NULL) || (b == NULL)) + goto err; + +#ifdef WIN16 + out=BIO_new(BIO_s_file_internal_w16()); +#else + out=BIO_new(BIO_s_file()); +#endif + if (out == NULL) exit(1); + BIO_set_fp(out,stdout,BIO_NOCLOSE); + + for (i=0; i<200; i++) + { + RAND_bytes(&c,1); + c=(c%BN_BITS)-BN_BITS2; + BN_rand(a,NUM_BITS+c,0,0); + + RAND_bytes(&c,1); + c=(c%BN_BITS)-BN_BITS2; + BN_rand(b,NUM_BITS+c,0,0); + + RAND_bytes(&c,1); + c=(c%BN_BITS)-BN_BITS2; + BN_rand(m,NUM_BITS+c,0,1); + + BN_mod(a,a,m,ctx); + BN_mod(b,b,m,ctx); + + ret=BN_mod_exp_mont(r_mont,a,b,m,ctx); + if (ret <= 0) + { printf("BN_mod_exp_mont() problems\n"); exit(1); } + + ret=BN_mod_exp_recp(r_recp,a,b,m,ctx); + if (ret <= 0) + { printf("BN_mod_exp_recp() problems\n"); exit(1); } + + if (BN_cmp(r_mont,r_recp) != 0) + { + printf("\nmont and recp results differ\n"); + printf("a (%3d) = ",BN_num_bits(a)); BN_print(out,a); + printf("\nb (%3d) = ",BN_num_bits(b)); BN_print(out,b); + printf("\nm (%3d) = ",BN_num_bits(m)); BN_print(out,m); + printf("\nrecp ="); BN_print(out,r_recp); + printf("\nmont ="); BN_print(out,r_mont); + printf("\n"); + exit(1); + } + else + { + printf("."); + fflush(stdout); + } + } + printf(" done\n"); + exit(0); +err: + ERR_load_crypto_strings(); + ERR_print_errors(out); + exit(1); + return(1); + } + diff --git a/crypto/bn/stuff/bn_knuth.c b/crypto/bn/stuff/bn_knuth.c new file mode 100644 index 0000000000..9a3f4130ed --- /dev/null +++ b/crypto/bn/stuff/bn_knuth.c @@ -0,0 +1,378 @@ +/* crypto/bn/bn_knuth.c */ + +#include <stdio.h> +#include "cryptlib.h" +#include "bn.h" + +/* This is just a test implementation, it has not been modified for + * speed and it still has memory leaks. */ + +int BN_mask_bits(BIGNUM *a,int n); + +#undef DEBUG +#define MAIN + +/* r must be different to a and b + * Toom-Cook multiplication algorithm, taken from + * The Art Of Computer Programming, Volume 2, Donald Knuth + */ + +#define CODE1 ((BIGNUM *)0x01) +#define CODE2 ((BIGNUM *)0x02) +#define CODE3 ((BIGNUM *)0x03) +#define MAXK (30+1) + +#define C3 3 +#define C4 4 +#define C5 5 +#define C6 6 +#define C7 7 +#define C8 8 +#define C9 9 +#define C10 10 +#define DONE 11 + +int new_total=0; +int Free_total=0; +int max=0,max_total=0; + +BIGNUM *LBN_new(void ); +BIGNUM *LBN_dup(BIGNUM *a); +void LBN_free(BIGNUM *a); + +int BN_mul_knuth(w, a, b) +BIGNUM *w; +BIGNUM *a; +BIGNUM *b; + { + int ret=1; + int i,j,n,an,bn,y,z; + BIGNUM *U[MAXK],*V[MAXK],*T[MAXK]; + BIGNUM *C[(MAXK*2*3)]; + BIGNUM *W[(MAXK*2)],*t1,*t2,*t3,*t4; + int Utos,Vtos,Ctos,Wtos,Ttos; + unsigned int k,Q,R; + unsigned int q[MAXK]; + unsigned int r[MAXK]; + int state; + + /* C1 */ + Utos=Vtos=Ctos=Wtos=Ttos=0; + k=1; + q[0]=q[1]=64; + r[0]=r[1]=4; + Q=6; + R=2; + + if (!bn_expand(w,BN_BITS2*2)) goto err; + an=BN_num_bits(a); + bn=BN_num_bits(b); + n=(an > bn)?an:bn; + while ((q[k-1]+q[k]) < n) + { + k++; + Q+=R; + i=R+1; + if ((i*i) <= Q) R=i; + q[k]=(1<<Q); + r[k]=(1<<R); + } +#ifdef DEBUG + printf("k ="); + for (i=0; i<=k; i++) printf("%7d",i); + printf("\nq[k]="); + for (i=0; i<=k; i++) printf("%7d",q[i]); + printf("\nr[k]="); + for (i=0; i<=k; i++) printf("%7d",r[i]); + printf("\n"); +#endif + + /* C2 */ + C[Ctos++]=CODE1; + if ((t1=LBN_dup(a)) == NULL) goto err; + C[Ctos++]=t1; + if ((t1=LBN_dup(b)) == NULL) goto err; + C[Ctos++]=t1; + + state=C3; + for (;;) + { +#ifdef DEBUG + printf("state=C%d, Ctos=%d Wtos=%d\n",state,Ctos,Wtos); +#endif + switch (state) + { + int lr,lq,lp; + case C3: + k--; + if (k == 0) + { + t1=C[--Ctos]; + t2=C[--Ctos]; +#ifdef DEBUG + printf("Ctos=%d poped %d\n",Ctos,2); +#endif + if ((t2->top == 0) || (t1->top == 0)) + w->top=0; + else + BN_mul(w,t1,t2); + + LBN_free(t1); /* FREE */ + LBN_free(t2); /* FREE */ + state=C10; + } + else + { + lr=r[k]; + lq=q[k]; + lp=q[k-1]+q[k]; + state=C4; + } + break; + case C4: + for (z=0; z<2; z++) /* do for u and v */ + { + /* break the item at C[Ctos-1] + * into lr+1 parts of lq bits each + * for j=0; j<=2r; j++ + */ + t1=C[--Ctos]; /* pop off u */ +#ifdef DEBUG + printf("Ctos=%d poped %d\n",Ctos,1); +#endif + if ((t2=LBN_dup(t1)) == NULL) goto err; + BN_mask_bits(t2,lq); + T[Ttos++]=t2; +#ifdef DEBUG + printf("C4 r=0 bits=%d\n",BN_num_bits(t2)); +#endif + for (i=1; i<=lr; i++) + { + if (!BN_rshift(t1,t1,lq)) goto err; + if ((t2=LBN_dup(t1)) == NULL) goto err; + BN_mask_bits(t2,lq); + T[Ttos++]=t2; +#ifdef DEBUG + printf("C4 r=%d bits=%d\n",i, + BN_num_bits(t2)); +#endif + } + LBN_free(t1); + + if ((t2=LBN_new()) == NULL) goto err; + if ((t3=LBN_new()) == NULL) goto err; + for (j=0; j<=2*lr; j++) + { + if ((t1=LBN_new()) == NULL) goto err; + + if (!BN_set_word(t3,j)) goto err; + for (i=lr; i>=0; i--) + { + if (!BN_mul(t2,t1,t3)) goto err; + if (!BN_add(t1,t2,T[i])) goto err; + } + /* t1 is U(j) */ + if (z == 0) + U[Utos++]=t1; + else + V[Vtos++]=t1; + } + LBN_free(t2); + LBN_free(t3); + while (Ttos) LBN_free(T[--Ttos]); + } +#ifdef DEBUG + for (i=0; i<Utos; i++) + printf("U[%2d]=%4d bits\n",i,BN_num_bits(U[i])); + for (i=0; i<Vtos; i++) + printf("V[%2d]=%4d bits\n",i,BN_num_bits(V[i])); +#endif + /* C5 */ +#ifdef DEBUG + printf("PUSH CODE2 and %d CODE3 onto stack\n",2*lr); +#endif + C[Ctos++]=CODE2; + for (i=2*lr; i>0; i--) + { + C[Ctos++]=V[i]; + C[Ctos++]=U[i]; + C[Ctos++]=CODE3; + } + C[Ctos++]=V[0]; + C[Ctos++]=U[0]; +#ifdef DEBUG + printf("Ctos=%d pushed %d\n",Ctos,2*lr*3+3); +#endif + Vtos=Utos=0; + state=C3; + break; + case C6: + if ((t1=LBN_dup(w)) == NULL) goto err; + W[Wtos++]=t1; +#ifdef DEBUG + printf("put %d bit number onto w\n",BN_num_bits(t1)); +#endif + state=C3; + break; + case C7: + lr=r[k]; + lq=q[k]; + lp=q[k]+q[k-1]; + z=Wtos-2*lr-1; + for (j=1; j<=2*lr; j++) + { + for (i=2*lr; i>=j; i--) + { + if (!BN_sub(W[z+i],W[z+i],W[z+i-1])) goto err; + BN_div_word(W[z+i],j); + } + } + state=C8; + break; + case C8: + y=2*lr-1; + if ((t1=LBN_new()) == NULL) goto err; + if ((t3=LBN_new()) == NULL) goto err; + + for (j=y; j>0; j--) + { + if (!BN_set_word(t3,j)) goto err; + for (i=j; i<=y; i++) + { + if (!BN_mul(t1,W[z+i+1],t3)) goto err; + if (!BN_sub(W[z+i],W[z+i],t1)) goto err; + } + } + LBN_free(t1); + LBN_free(t3); + state=C9; + break; + case C9: + BN_zero(w); +#ifdef DEBUG + printf("lq=%d\n",lq); +#endif + for (i=lr*2; i>=0; i--) + { + BN_lshift(w,w,lq); + BN_add(w,w,W[z+i]); + } + for (i=0; i<=lr*2; i++) + LBN_free(W[--Wtos]); + state=C10; + break; + case C10: + k++; + t1=C[--Ctos]; +#ifdef DEBUG + printf("Ctos=%d poped %d\n",Ctos,1); + printf("code= CODE%d\n",t1); +#endif + if (t1 == CODE3) + state=C6; + else if (t1 == CODE2) + { + if ((t2=LBN_dup(w)) == NULL) goto err; + W[Wtos++]=t2; + state=C7; + } + else if (t1 == CODE1) + { + state=DONE; + } + else + { + printf("BAD ERROR\n"); + goto err; + } + break; + default: + printf("bad state\n"); + goto err; + break; + } + if (state == DONE) break; + } + ret=1; +err: + if (ret == 0) printf("ERROR\n"); + return(ret); + } + +#ifdef MAIN +main() + { + BIGNUM *a,*b,*r; + int i; + + if ((a=LBN_new()) == NULL) goto err; + if ((b=LBN_new()) == NULL) goto err; + if ((r=LBN_new()) == NULL) goto err; + + if (!BN_rand(a,1024*2,0,0)) goto err; + if (!BN_rand(b,1024*2,0,0)) goto err; + + for (i=0; i<10; i++) + { + if (!BN_mul_knuth(r,a,b)) goto err; /**/ + /*if (!BN_mul(r,a,b)) goto err; /**/ + } +BN_print(stdout,a); printf(" * "); +BN_print(stdout,b); printf(" =\n"); +BN_print(stdout,r); printf("\n"); + +printf("BN_new() =%d\nBN_free()=%d max=%d\n",new_total,Free_total,max); + + + exit(0); +err: + ERR_load_crypto_strings(); + ERR_print_errors(stderr); + exit(1); + } +#endif + +int BN_mask_bits(a,n) +BIGNUM *a; +int n; + { + int b,w; + + w=n/BN_BITS2; + b=n%BN_BITS2; + if (w >= a->top) return(0); + if (b == 0) + a->top=w; + else + { + a->top=w+1; + a->d[w]&= ~(BN_MASK2<<b); + } + return(1); + } + +BIGNUM *LBN_dup(a) +BIGNUM *a; + { + new_total++; + max_total++; + if (max_total > max) max=max_total; + return(BN_dup(a)); + } + +BIGNUM *LBN_new() + { + new_total++; + max_total++; + if (max_total > max) max=max_total; + return(BN_new()); + } + +void LBN_free(a) +BIGNUM *a; + { + max_total--; + if (max_total > max) max=max_total; + Free_total++; + BN_free(a); + } diff --git a/crypto/bn/stuff/div.c b/crypto/bn/stuff/div.c new file mode 100644 index 0000000000..3d6e08622d --- /dev/null +++ b/crypto/bn/stuff/div.c @@ -0,0 +1,340 @@ +/* crypto/bn/div.c */ + +#include <stdio.h> +#include "cryptlib.h" +#include "bn.h" + +BN_ULONG bn_div_2word(); + +int BN_div2(dv, rm, num, div,ctx) +BIGNUM *dv; +BIGNUM *rm; +BIGNUM *num; +BIGNUM *div; +BN_CTX *ctx; + { + int norm_shift,i,j,nm,nd,loop; + BIGNUM *tmp,wnum,*snum,*sdiv,*res; + BN_ULONG *resp,*wnump; + BN_ULONG d0,d1; + int num_n,div_n; + +#ifdef DEBUG +BN_print(stdout,num); printf(" number\n"); +BN_print(stdout,div); printf(" divisor\n"); +#endif + if (BN_is_zero(num)) + { + BNerr(BN_F_BN_DIV,BN_R_DIV_BY_ZERO); + return(0); + } + + if (BN_cmp(num,div) < 0) + { + if (rm != NULL) + { if (BN_copy(rm,num) == NULL) return(0); } + if (dv != NULL) BN_zero(dv); + return(1); + } + + tmp=ctx->bn[ctx->tos]; + snum=ctx->bn[ctx->tos+1]; + sdiv=ctx->bn[ctx->tos+2]; + if (dv == NULL) + res=ctx->bn[ctx->tos+3]; + else res=dv; + + /* First we normalise the numbers */ + norm_shift=BN_BITS2-((BN_num_bits(div))%BN_BITS2); + BN_lshift(sdiv,div,norm_shift); + norm_shift+=BN_BITS2; + BN_lshift(snum,num,norm_shift); + div_n=sdiv->top; + num_n=snum->top; + loop=num_n-div_n; +#ifdef DEBUG +BN_print(stdout,snum); printf(" shifted num, forget last word\n"); +BN_print(stdout,sdiv); printf(" shifted div\n"); +#endif + + /* Lets setup a 'win'dow into snum + * This is the part that corresponds to the current + * 'area' being divided */ + wnum.d= &(snum->d[loop]); + wnum.top= div_n; + wnum.max= snum->max; /* a bit of a lie */ + wnum.neg= 0; + + /* Get the top 2 words of sdiv */ + i=sdiv->top; + d0=sdiv->d[div_n-1]; + d1=sdiv->d[div_n-2]; + + /* pointer to the 'top' of snum */ + wnump= &(snum->d[num_n-1]); + + /* Setup to 'res' */ + res->neg=0; + res->top=loop; + resp= &(res->d[loop-1]); + bn_expand(res,(loop+1)*BN_BITS2); + + /* space for temp */ + bn_expand(tmp,(div_n+1)*BN_BITS2); + +#ifdef DEBUG +printf("wnum="); BN_print(stdout,&wnum); printf(" initial sub check\n"); +printf("div ="); BN_print(stdout,sdiv); printf(" loop=%d\n",loop); +#endif + if (BN_cmp(&wnum,sdiv) >= 0) + { + BN_sub(&wnum,&wnum,sdiv); + *resp=1; + res->d[res->top-1]=1; + } + else + res->top--; + resp--; +#ifdef DEBUG +BN_print(stdout,res); printf(" initial result\n"); +BN_print(stdout,&wnum); printf(" wnum\n"); +#endif + + for (i=0; i<loop-1; i++) + { + BN_ULONG q,n0; + BN_ULLONG t1,t2,t3; + BN_ULONG l0; + + wnum.d--; + wnum.top++; + +#ifdef DEBUG +BN_print(stderr,&wnum); printf(" to divide\n"); +#endif + + q=0; + n0=wnump[0]; + t1=((BN_ULLONG)n0<<BN_BITS2)|wnump[-1]; + if (n0 == d0) + q=BN_MASK2; + else + { + t2=(t1/d0); + q=(t2&BN_MASK2); +#ifdef DEBUG +printf("t1=%08X / d0=%08X = %X (%X)\n",t1,d0,q,t2); +#endif + } + for (;;) + { + t2=(BN_ULLONG)d1*q; + t3=t1-(BN_ULLONG)q*d0; +#ifdef DEBUG +printf("d1*q= %X n01-q*d0 = %X\n",t2,t3); +#endif + if ((t3>>BN_BITS2) || + (t2 <= ((t3<<BN_BITS2)+wnump[-2]))) + break; +#ifdef DEBUG +printf("reduce q\n"); +#endif + q--; + } + l0=bn_mul_word(tmp->d,sdiv->d,div_n,q); + if (l0) + tmp->d[div_n]=l0; + else + tmp->d[div_n]=0; + for (j=div_n+1; j>0; j--) + if (tmp->d[j-1]) break; + tmp->top=j; + +#ifdef DEBUG +printf("q=%08X\n",q); +BN_print(stdout,&wnum); printf(" number\n"); +BN_print(stdout,tmp); printf(" subtract\n"); + +BN_print(stdout,snum); printf(" shifted number before\n"); +BN_print(stdout,&wnum); printf(" wnum before\n"); +#endif + j=wnum.top; + BN_sub(&wnum,&wnum,tmp); + snum->top=snum->top+wnum.top-j; + +#ifdef DEBUG +BN_print(stdout,&wnum); printf(" wnum after\n"); +BN_print(stdout,snum); printf(" shifted number after\n"); +#endif + + if (wnum.neg) + { + q--; + j=wnum.top; + BN_add(&wnum,&wnum,sdiv); + snum->top+=wnum.top-j; + fprintf(stderr,"addback\n"); +#ifdef DEBUG +BN_print(stdout,snum); printf("after addback************************:\n"); +#endif + } + *(resp--)=q; +#ifdef DEBUG +BN_print(stdout,res); printf(" result\n"); +#endif + wnump--; + } + if (rm != NULL) + BN_rshift(rm,snum,norm_shift); + return(1); + } + +main() + { + BIGNUM *a,*b,*c,*d; + BIGNUM *cc,*dd; + BN_CTX *ctx; + int i,x; + + a=BN_new(); + b=BN_new(); + c=BN_new(); + d=BN_new(); + cc=BN_new(); + dd=BN_new(); + ctx=BN_CTX_new(); + +for (i=0; i<10240; i++) + { + BN_rand(a,80,0,0); + BN_rand(b,60,0,0); + + BN_div2(d,c,a,b,ctx); + BN_div(dd,cc,a,b,ctx); + if ((BN_cmp(d,dd) != 0) || (BN_cmp(c,cc) != 0)) + { + BN_print(stderr,a); fprintf(stderr," / "); + BN_print(stderr,b); fprintf(stderr," d="); + BN_print(stderr,d); fprintf(stderr," r= "); + BN_print(stderr,c); fprintf(stderr,"\nd="); + BN_print(stderr,dd); fprintf(stderr," r= "); + BN_print(stderr,cc); fprintf(stderr,"\n"); + } + + } + +#ifdef undef +/* + BN_rand(a,600,0,0); + BN_rand(b,400,0,0); + for (i=0; i<2000000; i++) + { + BN_div2(d,c,a,b,ctx); + } +*/ +/* for (i=0;;) */ +/* for (i=0; i<0xffffffff; i++) + { + BN_ULONG rr,r,a,b,c; + BN_ULLONG l; + + a=rand()&BN_MASK2; + b=rand()&BN_MASK2; + for (;;) + { + c=rand()&BN_MASK2; + if (c) break; + } +/* for (x=1; x<256*256; x++) */ + { + c=x; + a=i>>8; + b=i&0xff; + a&= ~(0xFFFFFF<<(BN_num_bits_word(c))); + + r=bn_div_2word(a,b,c); + + rr=(BN_ULONG)((((BN_ULLONG)a<<BN_BITS2)|b)/c); + + if ((i & 0xfffff) == 0) fprintf(stderr,"%d\n",i,r,rr); +/*if (x == 255) + fprintf(stderr,"%6d/%3d = %4d %4d\n",(a<<8)|b,c,r,rr); */ + if (rr != r) + { + fprintf(stderr,"%8d %02X%02X / %02X = %02X %02X\n", + i,a,b,c,rr,r); + abort(); + } + } + } +#endif + } + +/* Divide h-l by d and return the result. */ +BN_ULONG bn_div_2word(l,h,d) +BN_ULONG l,h,d; + { + BN_ULONG dh,dl,q,ret=0,th,tl,t,top; + int i,count=2; + + if (d == 0) return(-1); + + i=BN_num_bits_word(d); + if ((i != BN_BITS2) && (h > 1<<i)) + { + fprintf(stderr,"Division would overflow\n"); + abort(); + } + i=BN_BITS2-i; + if (h >= d) h-=d; + + if (i) + { + d<<=i; + h=(h<<i)|(l>>(BN_BITS2-i)); + l<<=i; + } + dh=(d&BN_MASK2h)>>BN_BITS4; + dl=(d&BN_MASK2l); + for (;;) + { + if ((h>>BN_BITS4) == dh) + q=BN_MASK2l; + else + q=h/dh; + + for (;;) + { + t=(h-q*dh); + if ((t&BN_MASK2h) || + ((dl*q) <= ( + (t<<BN_BITS4)+ + ((l&BN_MASK2h)>>BN_BITS4)))) + break; + q--; + } + th=q*dh; + tl=q*dl; + t=(tl>>BN_BITS4); + tl=(tl<<BN_BITS4)&BN_MASK2h; + th+=t; + + if (l < tl) th++; + l-=tl; + if (h < th) + { + fprintf(stderr,"add back\n"); + h+=d; + q--; + } + h-=th; + + if (--count == 0) break; + + ret=q<<BN_BITS4; + h=((h<<BN_BITS4)|(l>>BN_BITS4))&BN_MASK2; + l=(l&BN_MASK2l)<<BN_BITS4; + } + ret|=q; + return(ret); + } diff --git a/crypto/bn/stuff/mont.doc b/crypto/bn/stuff/mont.doc new file mode 100644 index 0000000000..55d1d79312 --- /dev/null +++ b/crypto/bn/stuff/mont.doc @@ -0,0 +1,17 @@ +All numbers (a) are stored aR mod N (except abRR) + +RR = REDC(R*R) /* RR mod N */ + + +convert a -> aR +convert b -> bR + + { + abRR = aR * bR + abR = REDC(abRR); /* mod N */ + } + +ab = REDC(abR); /* mod N */ + + +REDC strips off a multiplicaion by R mod N diff --git a/crypto/bn/stuff/wei_mulw.c b/crypto/bn/stuff/wei_mulw.c new file mode 100644 index 0000000000..7f8a1e58fe --- /dev/null +++ b/crypto/bn/stuff/wei_mulw.c @@ -0,0 +1,410 @@ +/* crypto/bn/wei_mulw.c */ + +#include <stdio.h> +#include "cryptlib.h" +#include "bn.h" +#include "bn_lcl.h" + +BN_ULONG bn_add_word(BN_ULONG *a,BN_ULONG c,int num); +BN_ULONG bn_add_words(BN_ULONG *ret,BN_ULONG *a,BN_ULONG *b,int num); +BN_ULONG bn_sub_words(BN_ULONG *ret,BN_ULONG *a,BN_ULONG *b,int num); + +void BN_mul_4words(BN_ULONG *ret,BN_ULONG a0,BN_ULONG a1, + BN_ULONG b0,BN_ULONG b1); + +void pr(a,n,s) +BN_ULONG *a; +int n; + { + while (n--) + fprintf(stdout,"%02X",a[n]); + fprintf(stdout,"%s",s); + } + + +BN_ULONG bn_add_word(a,w,num) +BN_ULONG *a; +BN_ULONG w; +int num; + { + BN_ULONG t; + +#ifdef DEBUG +{ BN_ULONG *aa=a; int i; for (i=num; i>0; i--) fprintf(stdout,"%02X",aa[i-1]); +fprintf(stdout," + %X - ",w); i=num; +#endif + +loop: + t= *a; + t=(t+w)&BN_MASK2; + *(a++)=t; + w=(t < w); + if (w && --num) goto loop; + +#ifdef DEBUG +for (; i>0; i--) fprintf(stdout,"%02X",aa[i-1]); +fprintf(stdout,"\n"); +} +#endif + + return(w); + } + +BN_ULONG bn_add_words(r,a,b,num) +BN_ULONG *r; +BN_ULONG *a; +BN_ULONG *b; +int num; + { +#if defined(BN_LLONG) + BN_ULLONG t; + BN_ULONG c=0; + int i; + + if (num&1) abort(); + + for (i=0; i<num; i+=2) + { + t=(BN_ULLONG)a[i]+b[i]+c; + r[i+0]=L(t); + t=(BN_ULLONG) H(t)+a[i+1]+b[i+1]; + r[i+1]=L(t); + c=H(t); + } + return(c); +#else + BN_ULONG c=0,t1,t2; + + for ( ; num; num--) + { + t1= *(a++); + t2= *(b++); + + if (c) + { + c=(t2 >= ((~t1)&BN_MASK2)); + (*r++)=(t1+t2+1)&BN_MASK2; + } + else + { + t2=(t1+t2)&BN_MASK2; + c=(t2 < t1); + (*r++)=t2; + } + } + return(c); +#endif + } + +BN_ULONG bn_sub_words(r,a,b,num) +BN_ULONG *r; +BN_ULONG *a; +BN_ULONG *b; +int num; + { +#if defined(BN_LLONG) + BN_ULLONG t; + BN_ULONG c=0; + int i; + + if (num&1) abort(); + + for (i=0; i<num; i+=2) + { + t=(BN_ULLONG)a[i]-b[i]-c; + r[i+0]=L(t); + t=(BN_ULLONG)a[i+1]-b[i+1]-(0-H(t))&BN_MASK2; + r[i+1]=L(t); + c=H(t); + } + return(c); +#else + BN_ULONG c=0,t1,t2; + + for ( ; num; num--) + { + t1= *(a++); + t2= *(b++); + + if (c) + { + c=(t1 <= t2); + t1=(t1-t2-1); + } + else + { + c=(t1 < t2); + t1=(t1-t2); + } + (*r++)=t1&BN_MASK2; + } + return(c); +#endif + } + + +/* ret[3,2,1,0] = a1,a0 * b1,b0 */ +void BN_mul_4words(ret,a0,a1,b0,b1) +BN_ULONG *ret; +BN_ULONG a0,a1,b0,b1; + { + BN_ULONG s,u; + BN_ULLONG fix,a0b0,a1b1,tmp; + + if (a1 >= a0) + { + s=(a1-a0); + u=(b0-b1); + fix=(BN_ULLONG)s*u; + if (b0 >= b1) s=0; + } + else + { + BN_ULONG u; + + if (b0 > b1) + { + s=(b0-b1); + u=(a1-a0); + fix=(BN_ULLONG)s*u; + } + else + { + u=(a0-a1); + s=(b1-b0); + fix=(BN_ULLONG)s*u; + s=0; + } + } + + a0b0=(BN_ULLONG)a0*b0; + ret[0]=L(a0b0); + + a1b1=(BN_ULLONG)a1*b1; + tmp=(BN_ULLONG) H(a0b0) + L(a0b0) + L(fix) + L(a1b1); + ret[1]=L(tmp); + + tmp=(BN_ULLONG) a1b1 + H(tmp) + H(a0b0) + H(fix) + H(a1b1) - s; + ret[2]=L(tmp); + ret[3]=H(tmp); + } + +/* ret[3,2,1,0] += a1,a0 * b1,b0 */ +BN_ULONG BN_mul_add_4words(ret,a0,a1,b0,b1) +BN_ULONG *ret; +BN_ULONG a0,a1,b0,b1; + { + BN_ULONG s,u; + BN_ULLONG fix,a0b0,a1b1,tmp; + +#ifdef DEBUG +fprintf(stdout,"%02X%02X%02X%02X",ret[3],ret[2],ret[1],ret[0]); +fprintf(stdout," + ( %02X%02X * %02X%02X ) - ",a1,a0,b1,b0); +#endif + if (a1 >= a0) + { + s=(a1-a0); + u=(b0-b1); + fix=(BN_ULLONG)s*u; + if (b0 >= b1) s=0; + } + else + { + if (b0 > b1) + { + s=(b0-b1); + u=(a1-a0); + fix=(BN_ULLONG)s*u; + } + else + { + u=(a0-a1); + s=(b1-b0); + fix=(BN_ULLONG)s*u; + s=0; + } + } + + a0b0=(BN_ULLONG)a0*b0; + tmp=a0b0+ret[0]; + ret[0]=L(tmp); + + a1b1=(BN_ULLONG)a1*b1; + tmp=(BN_ULLONG) H(tmp) + L(a0b0) + L(fix) + L(a1b1) + ret[1]; + ret[1]=L(tmp); + + tmp=(BN_ULLONG) H(tmp) + L(a1b1) + H(a0b0) + + H(fix) + H(a1b1) -s + ret[2]; + ret[2]=L(tmp); + + tmp=(BN_ULLONG) H(tmp) + H(a1b1) + ret[3]; + ret[3]=L(tmp); +#ifdef DEBUG +fprintf(stdout,"%02X%02X%02X%02X%02X\n",H(tmp),ret[3],ret[2],ret[1],ret[0]); +#endif + return(H(tmp)); + } + +/* ret[3,2,1,0] += a1,a0 * a1,a0 */ +void BN_sqr_4words(ret,a0,a1) +BN_ULONG *ret; +BN_ULONG a0,a1; + { + BN_ULONG s,u; + BN_ULLONG tmp,tmp2; + + tmp=(BN_ULLONG)a0*a0; + ret[0]=L(tmp); + + tmp2=(BN_ULLONG)a0*a1; + tmp=(BN_ULLONG)H(tmp)+L(tmp2)*2; + ret[1]=L(tmp); + + tmp=(BN_ULLONG)a1*a1+H(tmp)+H(tmp2)*2; + ret[2]=L(tmp); + ret[3]=L(tmp); + } + +#define N0 (0) +#define N1 (half) +#define N2 (num) +#define N3 (num+half) + +#define word_cmp(r,a,b,num) \ + { \ + int n=num; \ +\ + (r)=0; \ + while (n--) \ + { \ + if ((a)[(n)] > (b)[(n)]) \ + { (r)=1; break; } \ + else if ((a)[(n)] < (b)[(n)]) \ + { (r)= -1; break; } \ + } \ + } + + +/* (a->top == b->top) && (a->top >= 2) && !(a->top & 1) */ +void bn_recursize_mul(r,t,a,b,num) +BN_ULONG *r,*t,*a,*b; +int num; + { + if ((num < 2) || (num&1)) + abort(); + +/* fprintf(stderr,"num=%d half=%d\n",num,num/2);*/ + if (num == 2) + BN_mul_4words(r,a[0],a[1],b[0],b[1]); + else if (num == 4) + { + BN_ULONG c,tmp; + + BN_mul_4words(&(r[0]),a[0],a[1],b[0],b[1]); + BN_mul_4words(&(r[4]),a[2],a[3],b[2],b[3]); + + c =BN_mul_add_4words(&(r[2]),a[0],a[1],b[2],b[3]); + c+=BN_mul_add_4words(&(r[2]),a[2],a[3],b[0],b[1]); + + bn_add_word(&(r[6]),c,2); + } + else + { + int half=num/2; + int carry,cmp_a,cmp_b; + + word_cmp(cmp_a,&(a[0]),&(a[half]),half); + word_cmp(cmp_b,&(b[0]),&(b[half]),half); + + switch (cmp_a*2+cmp_a+cmp_b) + { + case -4: + bn_sub_words(&(t[N0]),&(a[N1]),&(a[N0]),half); + bn_sub_words(&(t[N1]),&(b[N0]),&(b[N1]),half); + bn_recursize_mul(&(r[N1]),&(t[N2]), + &(t[N0]),&(t[N1]),half); + bn_sub_words(&(r[N2]),&(r[N2]),&(t[N0]),half); + carry= -1; + break; + case -2: + bn_sub_words(&(t[N0]),&(a[N1]),&(a[N0]),half); + bn_sub_words(&(t[N1]),&(b[N0]),&(b[N1]),half); + bn_recursize_mul(&(r[N1]),&(t[N2]), + &(t[N0]),&(t[N1]),half); + carry=0; + break; + case 2: + bn_sub_words(&(t[N0]),&(a[N0]),&(a[N1]),half); + bn_sub_words(&(t[N1]),&(b[N1]),&(b[N0]),half); + bn_recursize_mul(&(r[N1]),&(t[N2]), + &(t[N0]),&(t[N1]),half); + carry=0; + break; + case 4: + bn_sub_words(&(t[N0]),&(a[N1]),&(a[N0]),half); + bn_sub_words(&(t[N1]),&(b[N0]),&(b[N1]),half); + bn_recursize_mul(&(r[N1]),&(t[N2]), + &(t[N0]),&(t[N1]),half); + bn_sub_words(&(r[N2]),&(r[N2]),&(t[N1]),half); + carry= -1; + break; + default: + memset(&(r[N1]),0,sizeof(BN_ULONG)*num); + break; + } + + bn_recursize_mul(&(t[N0]),&(t[N2]),&(a[N0]),&(b[N0]),half); +#ifdef DEBUG + pr(a,half," * "); + pr(b,half," - "); + pr(t,num," - 0\n"); +#endif + memcpy(&(r[N0]),&(t[N0]),half*sizeof(BN_ULONG)); + if (bn_add_words(&(r[N1]),&(r[N1]),&(t[N1]),half)) + { bn_add_word(&(t[N1]),1,half); } + + carry+=bn_add_words(&(r[N1]),&(r[N1]),&(t[N0]),num); + + bn_recursize_mul(&(t[N0]),&(t[N2]),&(a[N1]),&(b[N1]),half); + + carry+=bn_add_words(&(r[N1]),&(r[N1]),&(t[N0]),num); + carry+=bn_add_words(&(r[N2]),&(r[N2]),&(t[N0]),half); + memcpy(&(r[N3]),&(t[N1]),half*sizeof(BN_ULONG)); + + bn_add_word(&(r[N3]),carry,half); + } + } + +main() + { + BIGNUM *a,*b,*r,*t; + int i,j; + + a=BN_new(); + b=BN_new(); + r=BN_new(); + t=BN_new(); + +#define BITS 1024 + bn_expand(r,BITS*2); + bn_expand(t,BITS*2); + fprintf(stdout,"obase=16\n"); + fprintf(stdout,"ibase=16\n"); + for (i=0; i<10; i++) + { + BN_rand(a,BITS,0,0); + BN_rand(b,BITS,0,0); + r->top=(BITS*2)/BN_BITS2; + memset(r->d,0,sizeof(r->top)*sizeof(BN_ULONG)); + memset(t->d,0,sizeof(r->top)*sizeof(BN_ULONG)); + for (j=0; j<1000; j++) + { + +/* BN_mul(r,a,b); /**/ + bn_recursize_mul(r->d,t->d,a->d,b->d,a->top); /**/ + } + BN_print(stdout,a); fprintf(stdout," * "); + BN_print(stdout,b); fprintf(stdout," - "); + BN_print(stdout,r); fprintf(stdout,"\n"); + } + } |