AVM$ENCRYPT IDENT

. This module contains the double precision arithmetic used to encrypt
. passwords on NOS/VE.
.
. The code for this module was generated by compiling the following FORTRAN
. subroutine and editing the object listing that was produced.
.
.     SUBROUTINE ENCRYPT (base, expon, coefi, prime, result)
.
.     INTEGER base, expon, coefi, prime, result
.     DOUBLE PRECISION rcoefi, rprime, rexpbas, rbase
.
.     rbase = base
.     rcoefi = coefi
.     rprime = prime
.
.     rexpbas = 1
.100  IF (expon.EQ.0) GO TO 200
.       IF (MOD(expon, 2).NE.0) THEN
.         rexpbas = DMOD ((rbase * rexpbas), rprime)
.       END IF
.       IF (expon.GT.1) THEN
.         rbase = DMOD ((rbase * rbase), rprime)
.       END IF
.       expon = expon / 2
.       GO TO 100
.200  CONTINUE
.     result = DMOD ((rcoefi * rexpbas), rprime)
.     END

AVP$ENCRYPT ALIGN           0,8
            DEF             AVP$ENCRYPT
            ADDAQ           A0,A0,72
            LA              A6,A4,8
            LA              A7,A4,0
            LA              A8,A4,16
            LA              A9,A4,24
            LA              AA,A4,32
            ENTE            XF,0E6(16)           .Deselect floating point loss of significance
            ENTE            X2,0FE87(16)
            CPYXS           X2,XF
            LX              XF,A7,0              .Get the base
            CNIF            X2,XF                .Convert to double precision
            CNFI            XD,X2
            ISOM            X3,X0,0,15
            ANDX            X3,X2
            BRXEQ           XD,XF,IL_1
            CPYXX           XE,XF
            SUBX            XE,XD
            CNIF            XD,XE
            ENTP            XE,0
            ADDD            X2,XD
IL_1        LX              XF,A8,0              .Get the coefficient
            CNIF            XD,XF                .Convert to double precision
            CNFI            XB,XD
            ISOM            XE,X0,0,15
            ANDX            XE,XD
            BRXEQ           XB,XF,IL_2
            CPYXX           XC,XF
            SUBX            XC,XB
            CNIF            XB,XC
            ENTP            XC,0
            ADDD            XD,XB
IL_2        SX              XD,A1,1*8            .Store the double precision coefficient
            SX              XE,A1,2*8
            LX              XF,A9,0              .Get the prime number
            CNIF            X4,XF                .Convert to double precision
            CNFI            XD,X4
            ISOM            X5,X0,0,15
            ANDX            X5,X4
            BRXEQ           XD,XF,IL_3
            CPYXX           XE,XF
            SUBX            XE,XD
            CNIF            XD,XE
            ENTP            XE,0
            ADDD            X4,XD
IL_3        SX              X4,A1,3*8            .Store the double precision prime
            SX              X5,A1,4*8
            LBYTP,8         X6,MAGIC_1           .Get the constant used to convert to integer
            LBYTP,8         X7,MAGIC_1+8
            LX              XA,A6,0              .Get the exponent
            LBYTP,8         X8,DP_ONE            .Initialize rexpbas to 1
            LBYTP,8         X9,DP_ONE+8
            ENTP            XB,2
            ENTP            XC,1
L100        BRXEQ           X0,XA,L200           .If the exponent is zero
            CPYXX           XF,XA                .Compute (exponent MOD 2)
            DIVX            XF,XB
            ADDX            XF,XF
            CPYXX           XE,XA
            SUBX            XE,XF
            BRXEQ           X0,XE,GL_2           .IF (exponent MOD 2) is zero
            MULD            X8,X2                .Compute ((rbase * rexpbas) DMOD rprime
            CPYXX           XE,X8
            CPYXX           XF,X9
            DIVD            XE,X4
            ADDD            XE,X6
            MULD            XE,X4
            SUBD            X8,XE
GL_2        BRXGE           XC,XA,GL_4
            MULD            X2,X2                .Compute ((rbase * rbase) DMOD rprime)
            CPYXX           XE,X2
            CPYXX           XF,X3
            DIVD            XE,X4
            ADDD            XE,X6
            MULD            XE,X4
            SUBD            X2,XE
GL_4        DIVX            XA,XB                .Compute (exponent / 2)
            BRXEQ           X0,X0,L100           .Continue the loop
L200        SX              XA,A6,0*8            .Store the exponent
            SX              X8,A1,5*8            .Store the double precision expanded base
            SX              X9,A1,6*8
            LX              XE,A1,1*8            .Get the double precision coefficient
            LX              XF,A1,2*8            .Compute ((rcoefi * rexpbas) DMOD rprime
            MULD            XE,X8
            LX              XC,A1,3*8            .Get the double precision prime
            LX              XD,A1,4*8
            CPYXX           XA,XE
            CPYXX           XB,XF
            DIVD            XA,XC
            LBYTP,8         X8,MAGIC_1
            LBYTP,8         X9,MAGIC_1+8
            ADDD            X8,XA
            MULD            X8,XC
            SUBD            XE,X8
            CPYXX           XD,XE
            CNFI            XD,XD
            LBYTP,8         XE,MAGIC_2
            MULF            XE,XF
            CNFI            XE,XE
            ADDX            XE,XD
            SX              XE,AA,0             .Store the result
            BRCR            12,4,EXIT           .Clear floating point loss of significance
EXIT        RETURN
dp_one      vfd,64    4001800000000000(16)      .Double precision one
            vfd,64    4001000000000000(16)
magic_1     vfd,64    4060000000000000(16)      .Double percision integer zero - used to remove the fraction
            vfd,64    4060000000000000(16)      .from a double precision number during DMOD function
magic_2     vfd,64    3fd1800000000000(16)      .Real number used to convert double precision to integer
            END

