]> gitweb.factorcode.org Git - factor.git/blob - extra/sodium/sodium.factor
sodium: the add essential crypto-box-* words and a unit-test
[factor.git] / extra / sodium / sodium.factor
1 ! Copyright (C) 2017 Alexander Ilin.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: byte-arrays init io.encodings.string io.encodings.utf8
4 kernel math sequences sodium.ffi ;
5 IN: sodium
6
7 ERROR: sodium-init-fail ;
8 ERROR: call-fail ;
9 ERROR: buffer-too-small ;
10
11 ! Call this before any other function, may be called multiple times.
12 : sodium-init ( -- ) sodium_init 0 < [ sodium-init-fail ] when ;
13
14 <PRIVATE
15
16 : cipher-buf ( message-length n -- byte-array )
17     + <byte-array> ;
18
19 : message-buf ( cipher-length n -- byte-array )
20     - <byte-array> ;
21
22 : secretbox-cipher-buf ( message-length -- byte-array )
23     crypto_secretbox_macbytes cipher-buf ;
24
25 : secretbox-message-buf ( cipher-length -- byte-array )
26     crypto_secretbox_macbytes message-buf ;
27
28 : box-cipher-buf ( message-length -- byte-array )
29     crypto_box_macbytes cipher-buf ;
30
31 : box-message-buf ( cipher-length -- byte-array )
32     crypto_box_macbytes message-buf ;
33
34 PRIVATE>
35
36 : random-bytes ( byte-array -- byte-array' )
37     dup dup length randombytes_buf ;
38
39 : n-random-bytes ( n -- byte-array )
40     <byte-array> random-bytes ;
41
42 : check0 ( n -- ) 0 = [ call-fail ] unless ;
43
44 : crypto-pwhash-str ( password opslimit memlimit -- str )
45     [ crypto_pwhash_strbytes <byte-array> dup ] 3dip
46     [ utf8 encode dup length ] 2dip crypto_pwhash_str check0
47     utf8 decode ;
48
49 : crypto-pwhash-str-verify ( str password -- bool )
50     [ utf8 encode ] bi@ dup length crypto_pwhash_str_verify 0 = ;
51
52 : crypto-generichash ( out-bytes in-bytes key-bytes/f -- out-bytes' )
53     [ dup ] 2dip [ dup length ] tri@ crypto_generichash check0 ;
54
55 : check-length ( byte-array min-length -- byte-array )
56     [ dup length ] dip < [ buffer-too-small ] when ;
57
58 : crypto-secretbox-easy ( msg-bytes nonce-bytes key-bytes -- cipher-bytes )
59     [ dup length [ secretbox-cipher-buf swap dupd ] keep ]
60     [ crypto_secretbox_noncebytes check-length ]
61     [ crypto_secretbox_keybytes check-length ] tri*
62     crypto_secretbox_easy check0 ;
63
64 : crypto-secretbox-open-easy ( cipher-bytes nonce-bytes key-bytes -- msg-bytes/f )
65     [
66         crypto_secretbox_macbytes check-length
67         dup length [ secretbox-message-buf swap dupd ] keep
68     ]
69     [ crypto_secretbox_noncebytes check-length ]
70     [ crypto_secretbox_keybytes check-length ] tri*
71     crypto_secretbox_open_easy 0 = [ drop f ] unless ;
72
73 : crypto-box-keypair ( -- public-key secret-key )
74     crypto_box_publickeybytes <byte-array>
75     crypto_box_secretkeybytes <byte-array>
76     2dup crypto_box_keypair check0 ;
77
78 : crypto-box-nonce ( -- nonce-bytes )
79     crypto_box_noncebytes n-random-bytes ;
80
81 : crypto-box-easy ( message nonce public-key private-key -- cipher-bytes )
82     [
83         dup length [ box-cipher-buf dup rot ] keep
84     ] 3dip crypto_box_easy check0 ;
85
86 : crypto-box-open-easy ( cipher-bytes nonce public-key private-key -- message )
87     [
88         dup length [ box-message-buf dup rot ] keep
89     ] 3dip crypto_box_open_easy check0 ;
90
91 [ sodium-init ] "sodium" add-startup-hook