### SSSS working (hi siiky!) added by C-Keen on Thu Feb 16 14:22:28 2023

```(import srfi-1 (math base) (math number-theory) srfi-4 (chicken bitwise))

(define (make-polynom x0 coefficients)
(lambda (x)
(apply + `(,x0 ,@(map (lambda (c i) (* c (expt x i))) coefficients (iota (length coefficients) 1))))))

(define (make-polynom-in-field x0 coefficients p)
(let ((f (make-polynom x0 coefficients)))
(lambda (x) (modulo (f x) p))))

(define (split-secret secret shares needed-for-recovery)
(let* ((number-of-coefficients (- shares needed-for-recovery))
(p (next-prime secret))
(cs (list-tabulate number-of-coefficients (lambda (i) (random-bits 128))))
(f (make-polynom-in-field secret cs p)))
(list `(n ,shares) `(k ,needed-for-recovery) `(p ,p) `(shares

(define (recover-secret p shares)
(modulo (fold (lambda (j acc) (+ acc (* (cdr j)
(fold (lambda (m acc)
(if (not (equal? m j))
(* acc (/ (car m) (- (car m) (car j))))
acc))
1 shares))))
0 shares)
p))

(define (test-it)
(let* ((secret 123456)
(stuff (split-secret secret 5 3))
(p (car (alist-ref 'p stuff)))
(prt (car (alist-ref 'shares stuff)))
(secret_restored (recover-secret p prt)))
(eq? secret_restored secret)))

;; These vectors are in reverse network byte ordering (LSB)
(define (u8vector->number v)
(let loop ((i (u8vector-length v))
(num 0))
(if (zero? i)
num
(loop (sub1 i)
(+ (arithmetic-shift num 8)
(u8vector-ref v (sub1 i)))))))

(define (number->u8vector number)
(define (determine-vector-length number)
(let loop ((n number)
(i 1))
(if (zero? (quotient n 256))
i
(loop (quotient n 256) (add1 i)))))
(let* ((size (determine-vector-length number))
(v (make-u8vector size 0)))
(let loop ((i size)
(num number))
(if (zero? i)
(if (zero? num)
v
;; Internal error
(error (sprintf "Number too large: ~A can't be split into an u8vector of ~A entries" number size)))
(begin
(u8vector-set! v (- size i) (inexact->exact (modulo num 256))) ; XXX
(loop (sub1 i) (quotient num 256)))))))

(define (string->secret str)
(u8vector->number (list->u8vector (map char->integer (string->list str)))))

(define (secret->string s)
(list->string (map integer->char (u8vector->list (number->u8vector s)))))

(define (test-it-again)
(let* ((secret "my secret passphrase, that I want to share with my friends")
(s (string->secret secret))
(shares (split-secret s 5 3)))
(print "Length secret: " (string-length secret) " s: " s)
(and (equal? s (recover-secret (car (alist-ref 'p shares)) (car (alist-ref 'shares shares))))
(secret->string (recover-secret (car (alist-ref 'p shares)) (car (alist-ref 'shares shares)))))))
```