A music player that connects to your cloud/distributed storage.
at main 139 lines 3.7 kB view raw
1module Cryptography.Hmac exposing (encrypt128, encrypt64) 2 3{-| Cryptography HMAC 4-} 5 6import Binary exposing (Bits) 7 8 9type alias HashFunction = 10 Bits -> Bits 11 12 13{-| HMAC encryption for hashing algorithms with a `blockSize` of 64. 14These include: SHA-0, SHA-1, SHA-224, SHA-256, MD5, etc. 15 16 >>> import Binary 17 >>> import SHA 18 19 >>> Binary.fromStringAsUtf8 "" 20 ..> |> encrypt64 SHA.sha256 "" 21 ..> |> Binary.toHex 22 ..> |> String.toLower 23 "b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad" 24 25 >>> Binary.fromStringAsUtf8 "key" 26 ..> |> encrypt64 SHA.sha256 "The quick brown fox jumps over the lazy dog" 27 ..> |> Binary.toHex 28 ..> |> String.toLower 29 "f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8" 30 31 >>> Binary.fromHex "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b" 32 ..> |> encrypt64 SHA.sha256 "Hi There" 33 ..> |> Binary.toHex 34 ..> |> String.toLower 35 "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7" 36 37 >>> Binary.fromHex "4a656665" 38 ..> |> encrypt64 SHA.sha256 "what do ya want for nothing?" 39 ..> |> Binary.toHex 40 ..> |> String.toLower 41 "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843" 42 43 >>> Binary.fromHex "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 44 ..> |> encrypt64 SHA.sha256 "Test Using Larger Than Block-Size Key - Hash Key First" 45 ..> |> Binary.toHex 46 ..> |> String.toLower 47 "60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54" 48 49-} 50encrypt64 : HashFunction -> String -> Bits -> Bits 51encrypt64 = 52 encrypt (64 * 8) 53 54 55{-| HMAC encryption for hashing algorithms with a `blockSize` of 128. 56These include: SHA-384, SHA-512, etc. 57-} 58encrypt128 : HashFunction -> String -> Bits -> Bits 59encrypt128 = 60 encrypt (128 * 8) 61 62 63 64-- ENCRYPT 65 66 67encrypt : Int -> HashFunction -> String -> Bits -> Bits 68encrypt blockSize hash messageString key = 69 let 70 keySize = 71 Binary.width key 72 73 keyWithBlockSize = 74 if keySize > blockSize then 75 padRight blockSize (hash key) 76 77 else if keySize < blockSize then 78 padRight blockSize key 79 80 else 81 key 82 83 ( binSeqOne, binSeqTwo ) = 84 Tuple.mapBoth 85 (Binary.xor keyWithBlockSize) 86 (Binary.xor keyWithBlockSize) 87 (padding <| blockSize // 8) 88 in 89 messageString 90 |> Binary.fromString 8 91 |> Binary.append binSeqOne 92 |> hash 93 |> Binary.append binSeqTwo 94 |> hash 95 96 97padRight : Int -> Bits -> Bits 98padRight int bits = 99 let 100 size = 101 Binary.width bits 102 in 103 False 104 |> List.repeat (int - size) 105 |> List.append (Binary.toBooleans bits) 106 |> Binary.fromBooleans 107 108 109 110-- PADDING 111 112 113padding : Int -> ( Bits, Bits ) 114padding blockSize = 115 case blockSize of 116 64 -> 117 padding64 118 119 128 -> 120 padding128 121 122 _ -> 123 ( Binary.concat (List.repeat blockSize <| Binary.fromHex "36") 124 , Binary.concat (List.repeat blockSize <| Binary.fromHex "5C") 125 ) 126 127 128padding64 : ( Bits, Bits ) 129padding64 = 130 ( Binary.concat (List.repeat 64 <| Binary.fromHex "36") 131 , Binary.concat (List.repeat 64 <| Binary.fromHex "5C") 132 ) 133 134 135padding128 : ( Bits, Bits ) 136padding128 = 137 ( Binary.concat (List.repeat 128 <| Binary.fromHex "36") 138 , Binary.concat (List.repeat 128 <| Binary.fromHex "5C") 139 )