Skip to content

Commit d4dc5cf

Browse files
committed
To just glue
1 parent cdfe601 commit d4dc5cf

File tree

12 files changed

+219
-303
lines changed

12 files changed

+219
-303
lines changed

bower.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,11 @@
2525
"output"
2626
],
2727
"dependencies": {
28-
"purescript-node-buffer": "^7.0.0"
28+
"purescript-node-buffer": "^7.0.0",
29+
"purescript-nullable": "^5.0.0",
30+
"purescript-aff": "^6.0.0"
2931
},
3032
"devDependencies": {
31-
"purescript-assert": "^5.0.0"
33+
"purescript-test-unit": "^16.0.0"
3234
}
3335
}

src/Node/Crypto.js

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,23 @@
22

33
var crypto = require('crypto');
44

5-
exports.timingSafeEqual = function(b1) {
6-
return function(b2) {
7-
return function() {
8-
return crypto.timingSafeEqual(b1, b2);
5+
exports.timingSafeEqualImpl = crypto.timingSafeEqual;
6+
7+
exports.randomBytesImpl = crypto.randomBytes;
8+
9+
exports.scryptImpl = function(password, salt, keylen) {
10+
return function(onError, onSuccess) {
11+
crypto.scrypt(password, salt, keylen, function(err, key) {
12+
if (err) {
13+
onError(err);
14+
} else {
15+
onSuccess(key);
16+
}
17+
});
18+
return function(cancelError, onCancelerError, onCancelerSuccess) {
19+
onCancelerSuccess({});
920
}
1021
}
1122
}
1223

13-
exports.randomBytes = function(size) {
14-
return function() {
15-
return crypto.randomBytes(size);
16-
}
17-
}
24+
exports.scryptSyncImpl = crypto.scryptSync;

src/Node/Crypto.purs

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,38 @@
1-
module Node.Crypto where
1+
module Node.Crypto
2+
( timingSafeEqual
3+
, randomBytes
4+
, scrypt
5+
, scryptSync
6+
) where
27

38
import Prelude
49

10+
import Data.Function.Uncurried (Fn3, runFn3)
511
import Effect (Effect)
6-
import Node.Buffer (Buffer, fromString, toString)
7-
import Node.Crypto.Hash (Algorithm(..))
8-
import Node.Crypto.Hmac (createHmac, digest, update)
9-
import Node.Encoding (Encoding(..))
12+
import Effect.Aff (Aff)
13+
import Effect.Aff.Compat (EffectFnAff, fromEffectFnAff)
14+
import Effect.Uncurried (EffectFn1, EffectFn2, EffectFn3, runEffectFn1, runEffectFn2, runEffectFn3)
15+
import Node.Buffer (Buffer)
1016

11-
timingSafeEqualString :: String -> String -> Effect Boolean
12-
timingSafeEqualString x1 x2 = do
13-
a1 <- fromString x1 UTF8
14-
a2 <- fromString x2 UTF8
15-
secret <- randomBytes 32 >>= toString UTF8
16-
b1 <- createHmac SHA256 secret >>= flip update a1 >>= digest
17-
b2 <- createHmac SHA256 secret >>= flip update a2 >>= digest
18-
conj (x1 == x2) <$> timingSafeEqual b1 b2
17+
-- | [https://nodejs.org/api/crypto.html#crypto_crypto_timingsafeequal_a_b](https://nodejs.org/api/crypto.html#crypto_crypto_timingsafeequal_a_b)
18+
timingSafeEqual :: Buffer -> Buffer -> Effect Boolean
19+
timingSafeEqual a b = runEffectFn2 timingSafeEqualImpl a b
1920

20-
foreign import timingSafeEqual :: Buffer -> Buffer -> Effect Boolean
21+
-- | [https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback](https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback)
22+
randomBytes :: Int -> Effect Buffer
23+
randomBytes size = runEffectFn1 randomBytesImpl size
2124

22-
foreign import randomBytes :: Int -> Effect Buffer
25+
-- | [https://nodejs.org/api/crypto.html#crypto_crypto_scrypt_password_salt_keylen_options_callback](https://nodejs.org/api/crypto.html#crypto_crypto_scrypt_password_salt_keylen_options_callback)
26+
scrypt :: Buffer -> Buffer -> Int -> Aff Buffer
27+
scrypt password salt keylen =
28+
fromEffectFnAff $ runFn3 scryptImpl password salt keylen
29+
30+
-- | [https://nodejs.org/api/crypto.html#crypto_crypto_scryptsync_password_salt_keylen_options](https://nodejs.org/api/crypto.html#crypto_crypto_scryptsync_password_salt_keylen_options)
31+
scryptSync :: Buffer -> Buffer -> Int -> Effect Buffer
32+
scryptSync password salt keylen =
33+
runEffectFn3 scryptSyncImpl password salt keylen
34+
35+
foreign import timingSafeEqualImpl :: EffectFn2 Buffer Buffer Boolean
36+
foreign import randomBytesImpl :: EffectFn1 Int Buffer
37+
foreign import scryptImpl :: Fn3 Buffer Buffer Int (EffectFnAff Buffer)
38+
foreign import scryptSyncImpl :: EffectFn3 Buffer Buffer Int Buffer

src/Node/Crypto/Cipher.js

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,12 @@
22

33
var crypto = require('crypto');
44

5-
exports._createCipher = function(algorithm) {
6-
return function(password) {
7-
return function() {
8-
return crypto.createCipher(algorithm, password);
9-
}
10-
}
11-
}
5+
exports.createCipherivImpl = crypto.createCipheriv;
126

13-
exports.update = function(cipher) {
14-
return function(buffer) {
15-
return function() {
16-
return cipher.update(buffer);
17-
}
18-
}
7+
exports.updateImpl = function(buffer, cipher) {
8+
return cipher.update(buffer);
199
}
2010

21-
exports.final = function(cipher) {
22-
return function() {
23-
return cipher.final();
24-
}
11+
exports.finalImpl = function(cipher) {
12+
return cipher.final();
2513
}

src/Node/Crypto/Cipher.purs

Lines changed: 31 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,43 @@
11
module Node.Crypto.Cipher
22
( Cipher
3-
, Algorithm(..)
4-
, Password
5-
, hex
6-
, base64
7-
, createCipher
3+
, createCipheriv
84
, update
95
, final
106
) where
117

12-
import Prelude
8+
import Data.Maybe (Maybe)
9+
import Data.Nullable (Nullable, toNullable)
1310
import Effect (Effect)
14-
import Node.Encoding (Encoding(UTF8, Hex, Base64))
15-
import Node.Buffer (Buffer, fromString, toString, concat)
16-
11+
import Effect.Uncurried (EffectFn1, EffectFn2, EffectFn3, runEffectFn1, runEffectFn2, runEffectFn3)
12+
import Node.Buffer (Buffer)
13+
14+
-- | [https://nodejs.org/api/crypto.html#crypto_class_cipher](https://nodejs.org/api/crypto.html#crypto_class_cipher)
15+
-- |
16+
-- | Usage:
17+
-- |
18+
-- | ```
19+
-- | buf <- Buffer.fromString "dummy" UTF8
20+
-- | pbuf <- Buffer.fromString "password" UTF8
21+
-- | sbuf <- Buffer.fromString "salt" UTF8
22+
-- | key <- Crypto.scryptSync pbuf sbuf 32
23+
-- | iv <- Buffer.fromString "iviviviviviviviv" UTF8
24+
-- | cip <- Cipher.createCipheriv "aes256" key (Just iv)
25+
-- | rbuf1 <- Cipher.update buf cip
26+
-- | rbuf2 <- Cipher.final cip
27+
-- | Buffer.concat [ rbuf1, rbuf2 ] >>= Buffer.toString Hex
28+
-- | ```
1729
foreign import data Cipher :: Type
1830

19-
data Algorithm
20-
= AES128
21-
| AES192
22-
| AES256
23-
24-
type Password = String
25-
26-
instance showAlgorithm :: Show Algorithm where
27-
show AES128 = "aes128"
28-
show AES192 = "aes192"
29-
show AES256 = "aes256"
30-
31-
hex
32-
:: Algorithm
33-
-> Password
34-
-> String
35-
-> Effect String
36-
hex alg password str = cipher alg password str Hex
37-
38-
base64
39-
:: Algorithm
40-
-> Password
41-
-> String
42-
-> Effect String
43-
base64 alg password str = cipher alg password str Base64
44-
45-
cipher
46-
:: Algorithm
47-
-> Password
48-
-> String
49-
-> Encoding
50-
-> Effect String
51-
cipher alg password str enc = do
52-
buf <- fromString str UTF8
53-
cip <- createCipher alg password
54-
rbuf1 <- update cip buf
55-
rbuf2 <- final cip
56-
rbuf <- concat [ rbuf1, rbuf2 ]
57-
toString enc rbuf
58-
59-
createCipher :: Algorithm -> Password -> Effect Cipher
60-
createCipher alg password = _createCipher (show alg) password
31+
createCipheriv :: String -> Buffer -> Maybe Buffer -> Effect Cipher
32+
createCipheriv alg key iv =
33+
runEffectFn3 createCipherivImpl alg key (toNullable iv)
6134

62-
foreign import _createCipher
63-
:: String
64-
-> String
65-
-> Effect Cipher
35+
update :: Buffer -> Cipher -> Effect Buffer
36+
update buf cipher = runEffectFn2 updateImpl buf cipher
6637

67-
foreign import update :: Cipher -> Buffer -> Effect Buffer
38+
final :: Cipher -> Effect Buffer
39+
final cipher = runEffectFn1 finalImpl cipher
6840

69-
foreign import final :: Cipher -> Effect Buffer
41+
foreign import createCipherivImpl :: EffectFn3 String Buffer (Nullable Buffer) Cipher
42+
foreign import updateImpl :: EffectFn2 Buffer Cipher Buffer
43+
foreign import finalImpl :: EffectFn1 Cipher Buffer

src/Node/Crypto/Decipher.js

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,12 @@
22

33
var crypto = require('crypto');
44

5-
exports._createDecipher = function(algorithm) {
6-
return function(password) {
7-
return function() {
8-
return crypto.createDecipher(algorithm, password);
9-
}
10-
}
11-
}
5+
exports.createDecipherivImpl = crypto.createDecipheriv;
126

13-
exports.update = function(decipher) {
14-
return function(buffer) {
15-
return function() {
16-
return decipher.update(buffer);
17-
}
18-
}
7+
exports.updateImpl = function(buffer, decipher) {
8+
return decipher.update(buffer);
199
}
2010

21-
exports.final = function(decipher) {
22-
return function() {
23-
return decipher.final();
24-
}
11+
exports.finalImpl = function(decipher) {
12+
return decipher.final();
2513
}

src/Node/Crypto/Decipher.purs

Lines changed: 31 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,43 @@
11
module Node.Crypto.Decipher
22
( Decipher
3-
, fromHex
4-
, fromBase64
5-
, createDecipher
3+
, createDecipheriv
64
, update
75
, final
86
) where
97

10-
import Prelude
8+
import Data.Maybe (Maybe)
9+
import Data.Nullable (Nullable, toNullable)
1110
import Effect (Effect)
12-
import Node.Encoding (Encoding(UTF8, Hex, Base64))
13-
import Node.Buffer (Buffer, fromString, toString, concat)
14-
import Node.Crypto.Cipher (Algorithm, Password)
15-
11+
import Effect.Uncurried (EffectFn1, EffectFn2, EffectFn3, runEffectFn1, runEffectFn2, runEffectFn3)
12+
import Node.Buffer (Buffer)
13+
14+
-- | [https://nodejs.org/api/crypto.html#crypto_class_decipher](https://nodejs.org/api/crypto.html#crypto_class_decipher)
15+
-- |
16+
-- | Usage:
17+
-- |
18+
-- | ```
19+
-- | buf <- Buffer.fromString "434cf3b56614fc8eb186ea866fbd33b4" Hex
20+
-- | pbuf <- Buffer.fromString "password" UTF8
21+
-- | sbuf <- Buffer.fromString "salt" UTF8
22+
-- | key <- Crypto.scryptSync pbuf sbuf 32
23+
-- | iv <- Buffer.fromString "iviviviviviviviv" UTF8
24+
-- | dec <- Decipher.createDecipheriv "aes256" key (Just iv)
25+
-- | rbuf1 <- Decipher.update buf dec
26+
-- | rbuf2 <- Decipher.final dec
27+
-- | Buffer.concat [ rbuf1, rbuf2 ] >>= Buffer.toString UTF8
28+
-- | ```
1629
foreign import data Decipher :: Type
1730

18-
fromHex
19-
:: Algorithm
20-
-> Password
21-
-> String
22-
-> Effect String
23-
fromHex alg password str = decipher alg password str Hex
24-
25-
fromBase64
26-
:: Algorithm
27-
-> Password
28-
-> String
29-
-> Effect String
30-
fromBase64 alg password str = decipher alg password str Base64
31-
32-
decipher
33-
:: Algorithm
34-
-> Password
35-
-> String
36-
-> Encoding
37-
-> Effect String
38-
decipher alg password str enc = do
39-
buf <- fromString str enc
40-
dec <- createDecipher alg password
41-
rbuf1 <- update dec buf
42-
rbuf2 <- final dec
43-
rbuf <- concat [ rbuf1, rbuf2 ]
44-
toString UTF8 rbuf
45-
46-
createDecipher :: Algorithm -> Password -> Effect Decipher
47-
createDecipher alg password = _createDecipher (show alg) password
31+
createDecipheriv :: String -> Buffer -> Maybe Buffer -> Effect Decipher
32+
createDecipheriv alg key iv =
33+
runEffectFn3 createDecipherivImpl alg key (toNullable iv)
4834

49-
foreign import _createDecipher
50-
:: String
51-
-> String
52-
-> Effect Decipher
35+
update :: Buffer -> Decipher -> Effect Buffer
36+
update buf decipher = runEffectFn2 updateImpl buf decipher
5337

54-
foreign import update :: Decipher -> Buffer -> Effect Buffer
38+
final :: Decipher -> Effect Buffer
39+
final decipher = runEffectFn1 finalImpl decipher
5540

56-
foreign import final :: Decipher -> Effect Buffer
41+
foreign import createDecipherivImpl :: EffectFn3 String Buffer (Nullable Buffer) Decipher
42+
foreign import updateImpl :: EffectFn2 Buffer Decipher Buffer
43+
foreign import finalImpl :: EffectFn1 Decipher Buffer

src/Node/Crypto/Hash.js

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,12 @@
22

33
var crypto = require('crypto');
44

5-
exports._createHash = function(algorithm) {
6-
return function() {
7-
return crypto.createHash(algorithm);
8-
}
9-
}
5+
exports.createHashImpl = crypto.createHash;
106

11-
exports.update = function(hash) {
12-
return function(buffer) {
13-
return function() {
14-
return hash.update(buffer);
15-
}
16-
}
7+
exports.updateImpl = function(buffer, hash) {
8+
return hash.update(buffer);
179
}
1810

19-
exports.digest = function(hash) {
20-
return function() {
21-
return hash.digest();
22-
}
11+
exports.digestImpl = function(hash) {
12+
return hash.digest();
2313
}

0 commit comments

Comments
 (0)