PNG  IHDR!@ PLTE>O`jqv @-tEXtPage
sodium.scm - metalympiada
git clone git://metalympiada.org/
Log | Files | README | LICENSE

sodium.scm (5326B)


   1 (define-module (sodium)
   2   #:export (generate-key
   3             encrypt
   4             decrypt
   5             hash-password
   6             verify-password
   7             base64-encode
   8             base64-decode))
   9 (use-modules (rnrs bytevectors)
  10              (system foreign))
  11 
  12 (define libsodium (dynamic-link "libsodium"))
  13 
  14 (define sodium-init (pointer->procedure int
  15                                         (dynamic-func "sodium_init" libsodium)
  16                                         '()))
  17 (if (equal? (sodium-init) -1) (begin
  18                                 (display "Not enough entropy to be secure")
  19                                 (quit)))
  20 
  21 (define KEYBYTES
  22     ((pointer->procedure size_t (dynamic-func "crypto_secretbox_keybytes" libsodium) '())))
  23 
  24 (define NONCEBYTES
  25     ((pointer->procedure size_t (dynamic-func "crypto_secretbox_noncebytes" libsodium) '())))
  26 
  27 (define MACBYTES
  28     ((pointer->procedure size_t (dynamic-func "crypto_secretbox_macbytes" libsodium) '())))
  29 
  30 (define SALTBYTES
  31     ((pointer->procedure size_t (dynamic-func "crypto_pwhash_saltbytes" libsodium) '())))
  32 
  33 (define STRBYTES
  34     ((pointer->procedure size_t (dynamic-func "crypto_pwhash_strbytes" libsodium) '())))
  35 
  36 (define OPSLIMIT
  37     ((pointer->procedure size_t (dynamic-func "crypto_pwhash_opslimit_interactive" libsodium) '())))
  38 
  39 (define MEMLIMIT
  40     ((pointer->procedure size_t (dynamic-func "crypto_pwhash_memlimit_interactive" libsodium) '())))
  41 
  42 (define (random-buffer size)
  43   (let ((buffer (make-bytevector size))
  44         (f (pointer->procedure void
  45                                (dynamic-func "randombytes_buf" libsodium)
  46                                (list '* size_t))))
  47        (f (bytevector->pointer buffer) size)
  48        buffer))
  49 
  50 (define (generate-key)
  51   (random-buffer KEYBYTES))
  52 
  53 (define (pointer-add pointer offset)
  54   (make-pointer (+ (pointer-address pointer) offset)))
  55 
  56 (define (encrypt message key)
  57   (let ((buffer (random-buffer (+ (bytevector-length message) NONCEBYTES MACBYTES)))
  58         (f (pointer->procedure int
  59                                (dynamic-func "crypto_secretbox_easy" libsodium)
  60                                (list '* '* size_t '* '*))))
  61        (f (pointer-add (bytevector->pointer buffer) NONCEBYTES)
  62           (bytevector->pointer message)
  63           (bytevector-length message)
  64           (bytevector->pointer buffer)
  65           (bytevector->pointer key))
  66        buffer))
  67 
  68 (define (decrypt message key)
  69   (let* ((buffer (make-bytevector (- (bytevector-length message) NONCEBYTES MACBYTES)))
  70          (f (pointer->procedure int
  71                                 (dynamic-func "crypto_secretbox_open_easy" libsodium)
  72                                 (list '* '* size_t '* '*)))
  73          (res (f (bytevector->pointer buffer)
  74                  (pointer-add (bytevector->pointer message) NONCEBYTES)
  75                  (- (bytevector-length message) NONCEBYTES)
  76                  (bytevector->pointer message)
  77                  (bytevector->pointer key))))
  78         (if (equal? res 0) buffer #f)))
  79 
  80 (define (hash-password password)
  81   (let ((buffer (make-bytevector STRBYTES))
  82         (f (pointer->procedure int
  83                                (dynamic-func "crypto_pwhash_str" libsodium)
  84                                (list '* '* size_t size_t size_t))))
  85        (f (bytevector->pointer buffer)
  86           (string->pointer password)
  87           (string-length password)
  88           OPSLIMIT
  89           MEMLIMIT)
  90        (pointer->string (bytevector->pointer buffer))))
  91 
  92 (define (verify-password password hash)
  93   (let* ((f (pointer->procedure int
  94                                 (dynamic-func "crypto_pwhash_str_verify" libsodium)
  95                                 (list '* '* size_t)))
  96          (res (f (string->pointer hash)
  97                  (string->pointer password)
  98                  (string-length password))))
  99         (equal? res 0)))
 100 
 101 (define B64_VARIANT 7)
 102 
 103 (define (base64-encode data)
 104   (let* ((el (pointer->procedure size_t
 105                                  (dynamic-func "sodium_base64_encoded_len" libsodium)
 106                                  (list size_t int)))
 107          (len (el (bytevector-length data) B64_VARIANT))
 108          (buffer (make-bytevector len))
 109          (f (pointer->procedure '*
 110                                 (dynamic-func "sodium_bin2base64" libsodium)
 111                                 (list '* size_t '* size_t int))))
 112         (f (bytevector->pointer buffer)
 113            len
 114            (bytevector->pointer data)
 115            (bytevector-length data)
 116            B64_VARIANT)
 117         (pointer->string (bytevector->pointer buffer))))
 118 
 119 (define (base64-decode str)
 120   (let* ((len (make-c-struct (list size_t) (list 0)))
 121          (maxlen (ceiling (* (/ (string-length str) 4) 3)))
 122          (buffer (make-bytevector maxlen))
 123          (f (pointer->procedure int
 124                                 (dynamic-func "sodium_base642bin" libsodium)
 125                                 (list '* size_t '* size_t '* '* '* int))))
 126         (f (bytevector->pointer buffer)
 127            maxlen
 128            (string->pointer str)
 129            (string-length str)
 130            %null-pointer
 131            len
 132            %null-pointer
 133            B64_VARIANT)
 134         (let ((outlen (car (parse-c-struct len (list size_t)))))
 135              (if (> outlen 0)
 136                  (pointer->bytevector (bytevector->pointer buffer) outlen)
 137                  buffer))))
B,qfIDATx[o#Gv& 4 [M=oe, X4.&jɰ x v<0v~JFX { ރshLWMR"<&DB3꯫{߫*2 /oZSSh0-@yLL ))N p4$KL CLE`:"r[ӦIC!4"T0nOC/dT`4$0y5؃ pp!vc6''p2E;8'v- &" ^/O. Gilq*9.yb"&BݤXL\c)mhNIIRX`R#ڄD,qDQLTdҮ '(2DɘF t'k~B>FO$-T\{*THM#„OSA '!"4A۞Z.LxK1 @cr'v 87]aO hY 덟c{ۜ;r]XU%RM૜i {c% ?Y$g*S?kJPuT Ǧ^l(”:][6ˣJ]Ytjq8fPƕvq\lZ5Oҕ\^AIAj<gZ<6%J9xv30A)0/FY\o<7", J"bcD p!3pJ̸riECmiR0^ӠMJՠR "pc͢zF7!Z۟eo𱪥 M .!rs:T[zR(iТ`}1)o2% ϡÌ"1ǝ{VBEEZaQ3Z [ +o\3I UqKZ2Qw4D&:%WB("4+(DV$FHhe$.[Hi&<9$Ҍ{>͈#E{ΗbO$#W.QVF$W 45ǏRqaOY]q-%?cv+ɥ5/f6q¡(@J&Fgrkx8ׁ3GrHQS`l\"{*}r#U_+BFcwN_K  HF*ُQ2z230; #O`gl[N\Apqa<:V9 uC·Z!<0D 1 ) 18C{X1$*lR x187=lRTGl$E@OnSEeXm )ن70 ;D $ à(ֳϳG06ֿ#/@qepE}+',/ +4@Β"bΞ7x$waeY #SDQ_vhg?# f7V|w[Ħiи<}Ҡ̢$Id7{l<N +lj436? '#ʗ֟GMf4ܐI왆U}W=lM|!^P5;nB\ {ֺsJT3`t*l6Oe8Y|}3}*lVRR||-?܄g͊WJ\8r35+vJoH=K[}*l@g^J^L[qUan,8[9[QRBoX 8`<1m1Lsl/n|;Ҡ&NhEHu;]N-CT0kDU>:9sPOSc*DVd$OҀ -8n(qo{uޙD(BfG~4)¿&(*&6F0SU{ gvFw8\Fۆx(>V<[?afQ +v&j?y֑ )T`{ref9Br~ 3K;o,љyӀAN%D2wIJ-@RG]ME7jYn:(ɻnXͭt ?DoiӵKiP V[MJE'f}F^>o{WDs2e zKC;KI>Ij*/ܞH֌JT@W/hg8W} GlLhXůGqi/Y] #7#K q.Z=x֎bDKgw[݇'Bր͋>K͵ܞjoAW r|ɔ/: C<ɵȜF}^,$).2C0/ZGo-HֲGPJ7gMG* l@]ӺGPd-2J[ZiX]`vGC8R<p6aYD_QTTXa܁]^E}_4N'O(gɬ3%0Xڟ/ q,^8Ln^)j);B ?")+߉;/3')ܦ^:DW̶EJIՠSPf7FQELfݚGk3gld[34-Frtqܐ5Q+W$!ϳ٫*B9- NxqX ,d.rd,fZ*1Hblu #6Msک%S``50 z[Y۪-1gIl%[Y 5\]~~kʔ_¦*RGy_9jfMmŦ>8I7%[-D(Tu:];DF(GGcq%S$m+8jt K^$0u7ut.Ƽu-l=abNx΋kfX振/KSnNXOddMLvM.,q؅r ]3:ODhTMyZ|ɸj1^odC]^`.i ̅Zs̩!vږjct9.&e(@R6eqd$$>zog 2x?;Ic-Z `c1ˣGuȥY Sulq \,-c!: ,8ctb)g)ʤP5ci`vD`/DnӠ<3ͯq^=FCUmD_xDd@'0@tμG@*ʴQ"xeyN31ew`TɓGQcPOgn 3±#OxeptxE%W:٭Ad[%EHDL(U!Ξ9B`=}ZQVJz17([e&*їiuVsPϝGt+N*{uE @8yB]N6r%5ڍe=@Aai>F--PPEa vs\ ňePGŃqr}q\8#H+K恎/<;`Yݯ='&uө!\Bn  SH7/^TDTV pXn]{h\͡R\:u$@ Kse>  &9IENDB`