.TITLE HPWD - hash user password
.IDENT 'V02-002'

; This code was gotten by disassembling the AUTHORIZE program.
; It is quite shameful that DEC has not seen fit to provide
; this as a system service.

;  If you want lots of good comments, see the fiche.

;	e _lib$code:_lib$code+68


; Inputs: PWDDSC -- Addres of password descriptor
;	  ENCRYPT -- Encryption algorithm index (byte)
;	  SALT - random number (word)
;	  USRDSC - Address of username descriptor

; output:  OUTDSC  -- Address of encrypted output descriptor

OUTDSC=4
PWDDSC=OUTDSC+4
ENCRYPT=PWDDSC+4
SALT=ENCRYPT+4
USRDSC=SALT+4

.PSECT _LIB$CODE	RD,NOWRT,PIC,SHR,BYTE,EXE

;  AUTODIN-II polynomial table used by CRC algorithm
AUTODIN:
	.LONG ^X000000000,^X01DB71064,^X03B6E20C8,^X026D930AC,^X076DC4190
	.LONG ^X06B6B51F4,^X04DB26158,^X05005713C,^X0EDB88320,^X0F00F9344
	.LONG ^X0D6D6A3E8,^X0CB61B38C,^X09B64C2B0,^X086D3D2D4,^X0A00AE278
	.LONG ^X0BDBDF21C

; Purdy polynomial coefficients.  Prime, but don't need to be
Purdy_Poly:
c:
	.LONG -83,-1
	.LONG -179,-1
	.LONG -257,-1
	.LONG -323,-1
	.LONG -363,-1

.ENTRY	LGI$HPWD,^M<R2,R3,R4>
	MOVAQ   @outdsc(AP),R4
	MOVAQ   @4(R4),R4
	TSTB    encrypt(AP)
	BGTRU   10$
	MNEGL   #1,R0
	MOVAQ   @pwddsc(AP),R1
	CRC     autodin,R0,(R1),@4(R1)
	CLRL    R1
	MOVQ    R0,(R4)
	BRB     20$

10$:	CLRQ    (R4)
	MOVAQ   @pwddsc(AP),R3
	BSBB    COLLAPSE_R2
	ADDW2   salt(AP),3(R4)
	MOVAQ   @usrdsc(AP),R3
	BSBB    COLLAPSE_R2
	PUSHAQ  (R4)
	CALLS   #1,PURDY

20$:	MOVL    #1,R0
	RET


COLLAPSE_R2:
	MOVZWL  (R3),R0
	BEQL    20$
	MOVAL   @4(R3),R2
	PUSHR	#^M<R1,R2>
	MOVL	R0,R1
5$:	CMPB	(R2)+,#32
	BNEQ	7$
	DECL	R1
7$:	SOBGTR  R0,5$
	MOVL	R1,R0
	POPR	#^M<R1,R2>
10$:	BICL3	#-8,R0,R1
	ADDB2   (R2)+,(R4)[R1]
	SOBGTR  R0,10$
20$:	RSB

a=59
n0=1@24-3
n1=1@24-63


.ENTRY	PURDY,^M<r2,r3,r4,r5>
	MOVQ	@4(AP),-(SP)
	BSBW	PQMOD_R0
	MOVAQ	(SP),R4
	MOVAQ	PURDY_POLY,R5
	MOVQ    (R4),-(SP)
	PUSHL   #n1
	BSBB    PQEXP_R3
	MOVQ    (R4),-(SP)
	PUSHL   #n0-n1
	BSBB    PQEXP_R3
	MOVQ    (R5)+,-(SP)
	BSBW    PQADD_R0
	BSBW    PQMUL_R2
	MOVQ    (R5)+,-(SP)
	MOVQ    (R4),-(SP)
	BSBW    PQMUL_R2
	MOVQ    (R5)+,-(SP)
	BSBW    PQADD_R0
	MOVQ    (R4),-(SP)
	BSBB    PQMUL_R2
	MOVQ    (R5)+,-(SP)
	BSBW    PQADD_R0
	MOVQ    (R4),-(SP)
	BSBB    PQMUL_R2
	MOVQ    (R5)+,-(SP)
	BSBW    PQADD_R0
	BSBW    PQADD_R0
	MOVQ    (SP)+,@4(AP)
	MOVL    #1,R0
	RET

PQEXP_R3:
	POPR    #^M<r3>
	MOVQ    #1,-(SP)
	MOVQ    8+4(SP),-(SP)
	TSTL    8+8(SP)
	BEQL    30$
10$:	BLBC    8+8(SP),20$
	MOVQ    (SP),-(SP)
	MOVQ    8+8(SP),-(SP)
	BSBB    PQMUL_R2
	MOVQ    (SP)+,8(SP)
	CMPZV   #1,#31,8+8(SP),#0
	BEQL    30$
20$:	MOVQ    (SP),-(SP)
	BSBB    PQMUL_R2
	EXTZV   #1,#31,8+8(SP),8+8(SP)
	BRB     10$

30$:	MOVQ    8(SP),8+8+4(SP)
	MOVAQ   8+8+4(SP),SP
	JMP     (R3)

u=0
v=u+4
y=u+8
z=y+4

PQMOD_R0:
	POPR    #^M<R0>
	CMPL    v(SP),#-1
	BLSSU   10$
	CMPL    u(SP),#-a
	BLSSU   10$
	ADDL2   #a,u(SP)
	ADWC    #0,v(SP)
10$:	JMP     (R0)

PQMUL_R2:
	POPR    #^M<r1>
	MOVL    SP,R2
	PUSHL   z(R2)
	PUSHL   v(R2)
	BSBB    EMULQ
	BSBB    PQMOD_R0
	BSBB    PQLSH_R0
	PUSHL   y(R2)
	PUSHL   v(R2)
	BSBB    EMULQ
	BSBB    PQMOD_R0
	PUSHL   z(R2)
	PUSHL   u(R2)
	BSBB    EMULQ
	BSBB    PQMOD_R0
	BSBB    PQADD_R0
	BSBB    PQADD_R0
	BSBB	PQLSH_R0
	PUSHL   y(R2)
	PUSHL	u(R2)
	BSBB	EMULQ
	BSBB    PQMOD_R0
	BSBB    PQADD_R0	
	MOVQ    (SP)+,Y(R2)
	MOVAQ   Y(R2),SP
	JMP     (R1)

EMULQ:
	EMUL    4(SP),8(SP),#0,-(SP)
	CLRL    -(SP)
	TSTL    4+8+4(SP)
	BGEQ    10$
	ADDL2   4+8+8(SP),(SP)
10$:	TSTL    4+8+8(SP)
	BGEQ    20$
	ADDL2   4+8+4(SP),(SP)
20$:	ADDL2   (SP)+,4(SP)
	MOVQ    (SP)+,4(SP)
	RSB     

PQLSH_R0:
.ENABLE LSB
	POPR    #^M<r0>
	PUSHL   v(SP)
	PUSHL   #a
	BSBB    EMULQ
	ASHQ    #32,Y(SP),Y(SP)
	BRB	10$

PQADD_R0:
	POPR    #^M<R0>
10$:	ADDL2   u(SP),y(SP)
	ADWC    v(SP),z(SP)
	BLSSU   20$
	CMPL    z(SP),#-1
	BLSSU   30$
	CMPL    y(SP),#-a
	BLSSU   30$
20$:	ADDL2   #a,y(SP)
	ADWC    #0,z(SP)
30$:	MOVAQ   Y(SP),SP
	JMP     (R0)
.END
