aboutsummaryrefslogtreecommitdiff
path: root/crypto/bn
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/bn')
-rw-r--r--crypto/bn/Makefile.ssl107
-rw-r--r--crypto/bn/asm/README30
-rw-r--r--crypto/bn/asm/alpha.s310
-rw-r--r--crypto/bn/asm/pa-risc.s710
-rw-r--r--crypto/bn/asm/pa-risc2.s416
-rw-r--r--crypto/bn/asm/r3000.s646
-rw-r--r--crypto/bn/asm/sparc.s359
-rw-r--r--crypto/bn/asm/x86-bsdi.s272
-rw-r--r--crypto/bn/asm/x86-lnx.s282
-rw-r--r--crypto/bn/asm/x86-lnxa.s282
-rw-r--r--crypto/bn/asm/x86-sol.s224
-rw-r--r--crypto/bn/asm/x86nt32.asm288
-rw-r--r--crypto/bn/asm/x86nt32.uu22
-rw-r--r--crypto/bn/asm/x86w16.asm297
-rw-r--r--crypto/bn/asm/x86w16.uu20
-rw-r--r--crypto/bn/asm/x86w32.asm303
-rw-r--r--crypto/bn/asm/x86w32.uu23
-rw-r--r--crypto/bn/bn.err20
-rw-r--r--crypto/bn/bn.h433
-rw-r--r--crypto/bn/bn.org433
-rw-r--r--crypto/bn/bn_add.c170
-rw-r--r--crypto/bn/bn_bld.c144
-rw-r--r--crypto/bn/bn_div.c286
-rw-r--r--crypto/bn/bn_err.c98
-rw-r--r--crypto/bn/bn_exp.c510
-rw-r--r--crypto/bn/bn_gcd.c203
-rw-r--r--crypto/bn/bn_lcl.h216
-rw-r--r--crypto/bn/bn_lib.c565
-rw-r--r--crypto/bn/bn_mod.c97
-rw-r--r--crypto/bn/bn_mont.c280
-rw-r--r--crypto/bn/bn_mul.c99
-rw-r--r--crypto/bn/bn_mulw.c303
-rw-r--r--crypto/bn/bn_prime.c389
-rw-r--r--crypto/bn/bn_prime.h325
-rw-r--r--crypto/bn/bn_prime.pl56
-rw-r--r--crypto/bn/bn_print.c218
-rw-r--r--crypto/bn/bn_rand.c121
-rw-r--r--crypto/bn/bn_recp.c125
-rw-r--r--crypto/bn/bn_shift.c210
-rw-r--r--crypto/bn/bn_sqr.c161
-rw-r--r--crypto/bn/bn_sub.c176
-rw-r--r--crypto/bn/bn_word.c155
-rw-r--r--crypto/bn/bnspeed.c240
-rw-r--r--crypto/bn/bntest.c775
-rw-r--r--crypto/bn/exptest.c148
-rw-r--r--crypto/bn/stuff/bn_knuth.c378
-rw-r--r--crypto/bn/stuff/div.c340
-rw-r--r--crypto/bn/stuff/mont.doc17
-rw-r--r--crypto/bn/stuff/wei_mulw.c410
49 files changed, 12692 insertions, 0 deletions
diff --git a/crypto/bn/Makefile.ssl b/crypto/bn/Makefile.ssl
new file mode 100644
index 0000000..cbddd4f
--- /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 0000000..d93fbff
--- /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 0000000..d56f715
--- /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 0000000..c49c433
--- /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 0000000..5e07b7d
--- /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 0000000..5be2a0d
--- /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 0000000..37c5fb1
--- /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 0000000..ca66876
--- /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 0000000..5123867
--- /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 0000000..74855dc
--- /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 0000000..c961e64
--- /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 0000000..0198c2c
--- /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 0000000..9920798
--- /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 0000000..6687491
--- /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 0000000..89c5e14
--- /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 0000000..0e4452d
--- /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 0000000..edcd84e
--- /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 0000000..5fe4b6d
--- /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 0000000..9326f4d
--- /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 0000000..9326f4d
--- /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 0000000..ecdb745
--- /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 0000000..966db43
--- /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 0000000..0ce4d41
--- /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 0000000..38818d6
--- /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 0000000..0a0db37
--- /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 0000000..9b0bc2b
--- /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 0000000..4d44651
--- /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 0000000..288ebca
--- /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 0000000..c94241f
--- /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 0000000..932d10b
--- /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 0000000..3c8bf23
--- /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 0000000..d903127
--- /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 0000000..07a8289
--- /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 0000000..1d6df58
--- /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 0000000..979385a
--- /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 0000000..36bc0d1
--- /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 0000000..e3530a5
--- /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 0000000..fd9ca4d
--- /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 0000000..d711887
--- /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 0000000..4c3f0a0
--- /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 0000000..b0febc3
--- /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 0000000..b61ddd9
--- /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 0000000..3b83a26
--- /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 0000000..7a2f0b8
--- /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 0000000..4880df1
--- /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 0000000..9a3f413
--- /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 0000000..3d6e086
--- /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 0000000..55d1d79
--- /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 0000000..7f8a1e5
--- /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");
+ }
+ }