Function: ntlm--bignat-mul

ntlm--bignat-mul is a byte-compiled function defined in ntlm.el.gz.

Signature

(ntlm--bignat-mul A B)

Documentation

Multiply the bignats A and B.

Source Code

;; Defined in /usr/src/emacs/lisp/net/ntlm.el.gz
;; Poor man's bignums: natural numbers represented as lists of bytes
;; in little-endian order.
;; When this code no longer needs to run on Emacs 26 or older, all this
;; silliness should be simplified to use ordinary Lisp integers.

(eval-and-compile                       ; for compile-time simplification
  (defun ntlm--bignat-of-int (x)
    "Convert the natural number X into a bignat."
    (declare (pure t))
    (and (not (zerop x))
         (cons (logand x #xff) (ntlm--bignat-of-int (ash x -8)))))

  (defun ntlm--bignat-add (a b &optional carry)
    "Add the bignats A and B and the natural number CARRY."
    (declare (pure t))
    (and (or a b (and carry (not (zerop carry))))
         (let ((s (+ (if a (car a) 0)
                     (if b (car b) 0)
                     (or carry 0))))
           (cons (logand s #xff)
                 (ntlm--bignat-add (cdr a) (cdr b) (ash s -8))))))

  (defun ntlm--bignat-shift-left (x n)
    "Multiply the bignat X by 2^{8N}."
    (declare (pure t))
    (if (zerop n) x (ntlm--bignat-shift-left (cons 0 x) (1- n))))

  (defun ntlm--bignat-mul-byte (a b)
    "Multiply the bignat A with the byte B."
    (declare (pure t))
    (let ((p (mapcar (lambda (x) (* x b)) a)))
      (ntlm--bignat-add
       (mapcar (lambda (x) (logand x #xff)) p)
       (cons 0 (mapcar (lambda (x) (ash x -8)) p)))))

  (defun ntlm--bignat-mul (a b)
    "Multiply the bignats A and B."
    (declare (pure t))
    (and a b (ntlm--bignat-add (ntlm--bignat-mul-byte a (car b))
                               (cons 0 (ntlm--bignat-mul a (cdr b))))))

  (defun ntlm--bignat-of-string (s)
    "Convert the string S (in decimal) to a bignat."
    (declare (pure t))
    (ntlm--bignat-of-digits (reverse (string-to-list s))))

  (defun ntlm--bignat-of-digits (digits)
    "Convert the little-endian list DIGITS of decimal digits to a bignat."
    (declare (pure t))
    (and digits
         (ntlm--bignat-add
          nil
          (ntlm--bignat-mul-byte (ntlm--bignat-of-digits (cdr digits)) 10)
          (- (car digits) ?0))))

  (defun ntlm--bignat-to-int64 (x)
    "Convert the bignat X to a 64-bit little-endian number as a string."
    (declare (pure t))
    (apply #'unibyte-string (mapcar (lambda (n) (or (nth n x) 0))
                                    (number-sequence 0 7))))
  )