#!/home/arne/wisp/wisp-multiline.sh -l guile
; !#
define-module : examples tinyenc
. #:export : encrypt decrypt
. #:use-syntax : ice-9 syncase
; http://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm#toctitle
define delta #x9e3779b9
define : uint32 number
. "ensure that the number fits a uint32"
modulo number : integer-expt 2 32
define : v0change k0 v1 sum k1
; format #t "sum: ~A, + k0 : ash v1 4: ~A, + v1 sum: ~A, + k1 : ash v1 -5: ~A\n"
; . sum
; uint32 : + k0 : ash v1 4
; uint32 : + v1 sum
; uint32 : + k1 : uint32 : ash v1 -5
logxor
uint32 : + k0 : ash v1 4
uint32 : + v1 sum
uint32 : + k1 : uint32 : ash v1 -5
define : v1change k2 v0 sum k3
logxor
uint32 : + k2 : ash v0 4
uint32 : + v0 sum
uint32 : + k3 : uint32 : ash v0 -5
; TODO: Define a macro with-split-kv which executes its body with let bindings to k0 k1 k2 k3 v0 and v1
; http://www.gnu.org/software/guile/manual/html_node/Syntax-Case.html#index-with_002dsyntax
define-syntax with-split-vk
syntax-rules :
: with-split-vk v k exp exp* ...
let
: v0 : uint32 : ash v -32
v1 : uint32 v
k0 : uint32 : ash k -96
k1 : uint32 : ash k -64
k2 : uint32 : ash k -32
k3 : uint32 k
. exp exp* ...
define : encrypt v k
. "Encrypt the 64bit (8 byte, big endian) value V with the 128bit key K (16 byte)."
; with-split-vk v k
let
: k0 : uint32 : ash k -96
k1 : uint32 : ash k -64
k2 : uint32 : ash k -32
k3 : uint32 k
v0 : uint32 : ash v -32
v1 : uint32 v
let loop
: sum delta
cycle 0
v0 v0
v1 v1
; format #t "v0: ~A, v1: ~A\n" v0 v1
; if (= cycle 32) : format #t "k0: ~A, k1: ~A, k2: ~A, k3: ~A\n" k0 k1 k2 k3
if : = cycle 32
+ v1 : * v0 : integer-expt 2 32
let : : v0tmp : uint32 : + v0 : v0change k0 v1 sum k1
loop
uint32 : + sum delta
+ cycle 1
. v0tmp
uint32 : + v1 : v1change k2 v0tmp sum k3
define : decrypt v k
. "Decrypt the 64bit (8 byte, big endian) value V with the 128bit key K (16 byte)."
let
: k0 : uint32 : ash k -96
k1 : uint32 : ash k -64
k2 : uint32 : ash k -32
k3 : uint32 k
v0 : uint32 : ash v -32
v1 : uint32 v
let loop
: sum #xc6ef3720
cycle 0
v0 v0
v1 v1
if : = cycle 32
+ v1 : * v0 : integer-expt 2 32
let : : v1tmp : uint32 : - v1 : v1change k2 v0 sum k3
loop
uint32 : - sum delta
+ cycle 1
uint32 : - v0 : v0change k0 v1tmp sum k1
. v1tmp
format #t "decrypted: ~A\n"
decrypt
encrypt
. 5
. 9
. 9
format #t "encrypted: ~A\n"
encrypt
. 5
. 9