thephoeron / cl-isaac

Optimized Common Lisp version of Bob Jenkins' ISAAC-32 and ISAAC-64 algorithms, fast cryptographic random number generators.
http://thephoeron.github.io/cl-isaac/
Other
25 stars 11 forks source link

Error in 32 bit CCL on Windows #3

Open inaimathi opened 9 years ago

inaimathi commented 9 years ago

Steps to reproduce:

  1. Run ccl
  2. Load cl-isaac
  3. Evaluate `(cl-isaac:init-common-lisp-random-seed)

Here's my repl session:

; SLIME 2013-04-02
CL-USER> (ql:quickload :cl-isaac)
To load "cl-isaac":
  Load 1 ASDF system:
    cl-isaac
; Loading "cl-isaac"

(:CL-ISAAC)
CL-USER> (cl-isaac:init-common-lisp-random-seed)

and here's the error dump

The value 34950810361856 is not of the expected type (UNSIGNED-BYTE 32).
  [Condition of type TYPE-ERROR] 

 Restarts:
   0: [RETRY] Retry SLIME REPL evaluation request.
   1: [*ABORT] Return to SLIME's top level.
   2: [ABORT-BREAK] Reset this thread
   3: [ABORT] Kill this thread

Backtrace:
  0: (CL-ISAAC:GENERATE-NEXT-ISAAC-BLOCK #S(CL-ISAAC:ISAAC-CTX :RANDCNT 0 :RANDRSL #(4181815078 2982827587 2809737237 3507203205 2611067200 224360919 ...) :RANDMEM ...))
  1: (CL-ISAAC:SCRAMBLE #S(CL-ISAAC:ISAAC-CTX :RANDCNT 0 :RANDRSL #(4181815078 2982827587 2809737237 3507203205 2611067200 224360919 ...) :RANDMEM ...))
  2: (CCL::CALL-CHECK-REGS CL-ISAAC:INIT-COMMON-LISP-RANDOM-SEED)
  3: (CCL::CHEAP-EVAL (CL-ISAAC:INIT-COMMON-LISP-RANDOM-SEED))
  4: (SWANK::EVAL-REGION "(cl-isaac:init-common-lisp-random-seed)\n")
  5: ((:INTERNAL SWANK::REPL-EVAL))
  6: (SWANK::TRACK-PACKAGE #<COMPILED-LEXICAL-CLOSURE (:INTERNAL SWANK::REPL-EVAL) #xCAEFC9E>)
  7: (SWANK::CALL-WITH-RETRY-RESTART "Retry SLIME REPL evaluation request." #<COMPILED-LEXICAL-CLOSURE (:INTERNAL SWANK::REPL-EVAL) #xCAEFCEE>)
  8: (SWANK::CALL-WITH-BUFFER-SYNTAX NIL #<COMPILED-LEXICAL-CLOSURE (:INTERNAL SWANK::REPL-EVAL) #xCAEFD16>)
  9: (SWANK::REPL-EVAL "(cl-isaac:init-common-lisp-random-seed)\n")
 10: (CCL::CALL-CHECK-REGS SWANK:LISTENER-EVAL "(cl-isaac:init-common-lisp-random-seed)\n")
 11: (CCL::CHEAP-EVAL (SWANK:LISTENER-EVAL "(cl-isaac:init-common-lisp-random-seed)\n"))
 12: (SWANK:EVAL-FOR-EMACS (SWANK:LISTENER-EVAL "(cl-isaac:init-common-lisp-random-seed)\n") "COMMON-LISP-USER" 7)
 13: (SWANK::PROCESS-REQUESTS NIL)
 14: ((:INTERNAL SWANK::HANDLE-REQUESTS))
 15: ((:INTERNAL SWANK::HANDLE-REQUESTS))
 16: (SWANK-BACKEND:CALL-WITH-DEBUGGER-HOOK #<Compiled-function SWANK:SWANK-DEBUGGER-HOOK #xC96BD8E> #<COMPILED-LEXICAL-CLOSURE (:INTERNAL SWANK::HANDLE-REQUESTS) #xCAB33A6>)
 17: (SWANK::CALL-WITH-BINDINGS ((*STANDARD-OUTPUT* . #<SWANK-BACKEND::SLIME-OUTPUT-STREAM #xCAAA056>) (*STANDARD-INPUT* . #<SWANK-BACKEND::SLIME-INPUT-STREAM #xCAAA266>) ..))) #<COMPILED-LEXICAL-CLOSURE (..
 18: (SWANK::HANDLE-REQUESTS #<MULTITHREADED-CONNECTION #xC9B693E> NIL)
 19: (CCL::RUN-PROCESS-INITIAL-FORM #<PROCESS repl-thread(12) [Active] #xCAAA516> (#<COMPILED-LEXICAL-CLOSURE (:INTERNAL CCL::%PROCESS-RUN-FUNCTION) #xCAAA3CE>))
 20: ((:INTERNAL (CCL::%PROCESS-PRESET-INTERNAL (PROCESS))) #<PROCESS repl-thread(12) [Active] #xCAAA516> (#<COMPILED-LEXICAL-CLOSURE (:INTERNAL CCL::%PROCESS-RUN-FUNCTION) #xCAAA3CE>))
 21: ((:INTERNAL CCL::THREAD-MAKE-STARTUP-FUNCTION))
thephoeron commented 9 years ago

Cannot reproduce in CCL 1.10 on Linux—and don't have Windows to test this myself. The integer 34950810361856 requires 45-bits, however—can you identify in the backtrace where it's coming from (more specifically than somewhere in generate-next-isaac-block)?

Also, which versions of Windows and CCL has this appeared?

inaimathi commented 9 years ago

It's CCL 1.09-r15764, running on Windows 7 SP1. I can't be much more specific, sadly; I only know that it happens somewhere in the loop body, and it seems to consistently hit at either i=2 or i=4.

thephoeron commented 9 years ago

Would you be able to take a sample from CCL 1.09-r15764 of (random (ash 1 32)) and test each value r with (integer-length r), and let me know if any of the integer-length values exceed 32-bits, and how many of them do? A sample-size of 10,000 should be fine.

inaimathi commented 9 years ago

Hm.

Looks like

CL-USER> (loop repeat 100000 for r = (random (ash 1 32))
            when (> (integer-length r) 32)
            collect (list r (integer-length r)))
NIL
CL-USER>

That is an intentional 100,000 in the repeat clause. I then loaded in cl-isaac and tried to eval init-common-lisp-random-seed; it still gives me the same UNSIGNED-BYTE error I mention in the bug report.

Anything else I could try?

thephoeron commented 9 years ago

Hmmm. Try fiddling with logxor and logand of #xFFFFFFFF to r, in the above loop? It looks like one of the values it's trying to assign to slots A, B, and C on ISAAC-CTX are too large. The value should never exceed the order of #xFFFFFFFF.

Another point of issue could be the use of (the (unsigned-byte 32)). Could you experiment with CCL's handling of that with a manually built context?

Also, does the same error happen on CCL 1.10, on Windows?

PuercoPop commented 6 years ago

I encounter the same problem on recentish (~2 months old?) SBCL. The problem occurs in this line. https://github.com/thephoeron/cl-isaac/blob/938318303d31a7be886ce3b68b427b087d519d90/isaac-32.lisp#L28

Note that because I restrict my compiler policy in my RC file, the code is compiled with different optimize settings than the default.

(sb-ext:restrict-compiler-policy 'debug 1)
(sb-ext:restrict-compiler-policy 'safety 1)

I fixed the issue by moving the type assertion after performing the bitmasking. This seems correct as we can't guarantee that the result of shifting an (unsigned-byte 32) is another (unsigned-byte 32). I.e.

...
(logxor (isaac-ctx-a ctx)
                  (the (unsigned-byte 32)
                       (logand #xFFFFFFFF
                               (ash (isaac-ctx-a ctx)
                                    (ecase (logand i 3)
                                      ((0) 13)
                                      ((1) -6)
                                      ((2) 2)
                                      ((3) -16))))))
...

I encountered the problem trying to use https://github.com/inaimathi/session-token.

(session-token:init-kernel-seed)
thephoeron commented 6 years ago

@PuercoPop thanks for letting me know! That's a good point about guaranteeing the result of the shift.