;input
; R5: msg
; R6: p
; R7: q
; R8: iq
; R9: dp
; RA: dq
;output
; R0: CRT( msg ** dp [p], msg ** dq [q] )
main:
    MOV     R0, R5
    MOV     R1, RF
    CMP     R5, RF
    JCR     messageOK
    STP                 ;message to sign is 0 or 1
messageOK:
    ;Save msg, p and prepare exponentiation
    MOV     RB, R6      ;RB = p
    MOV     R6, R7
    MOV     R7, RA
    MOV     RA, R5      ;RA = msg
    ;Compute Sq
    CA      exponentiation
    MOV     RC, R6      ;RC = q
    ;Compute Sp
    MOV     R5, RA
    MOV     RA, R0      ;RA = Sq
    MOV     R6, RB
    MOV     R7, R9
    CA      exponentiation
    ;Compute S = [(Sp-Sq)*iq mod p] * q + Sq
    ADD     R0, R0, R6
    ADD     R0, R0, R6
    MOV     R3, RA
    SUB     R0, R0, R3
    MOVRR   R1
    MOV     R7, R8
    MM      R0, R0, R1
    MM      R7, R7, R1
    MM      R0, R0, R7
    MM1     R0, R0
    MOV     R2, RC
    MUL     R0, R0, R2
    ADD     R0, R0, R3
    STP

; R1: 1
; R5: msg       (size of public modulus)
; R6: modulus
; R7: exponent
; R0: msg**exponent [modulus]
exponentiation:
    MOV     RD, RE                  ;Save LR
    BTL     R3, R6
    ADD     R4, R3, R3
    FP      R6, R4                  ;FP with modulus on double size
    MOVRR   R4
    MM1     R5, R5
    MM      R5, R5, R4              ;msg mod modulus
    MOV     R2, #64
    SLL     R2, R4, R2
    MM1     R2, R2                  ;RR for modulus on simple size
    FPRR    R2, R6, R3
    MM      R5, R5, R2              ;msg in Montgomery format
    MM1     R0, R2                  ;initialize result with 1.R
    MOV     R4, =tabOperation
    JR      startExponentiation_loop
exponentiation_loop:
    AND     R2, R7, R1              ;get lsb
    SRL     R7, R7, R1              ;drop lsb
    ADD     R2, R2, R4              ;select operation according to lsb
    MOVCW   R2
    CA      R2
startExponentiation_loop:
    SUB     R3, R3, R1
    JCR     exponentiation_loop
    MM1     R0, R0
    MOV     RE, RD                  ;Restore LR
    RET
tabOperation:
    .word   =bit0, =bit1

bit1:
    MM      R0, R0, R0
    MM      R0, R0, R5
    RET
bit0:
    MM      R5, R5, R5
    MM      R5, R5, R0
    RET