ktonon / elm-word / Word

Unsigned 32 or 64 bit integers and related operations.

Table of Contents

This package was developed to facilitate computations for SHA-2. It contains the minimal set of functions required by those algorithms.

Types


type Word
    = W Basics.Int
    | D Basics.Int Basics.Int
    | Mismatch

Unsigned integers of size 32 or 64 bits.

These constructors are provided as a convenience, but are unsafe. Use fromBytes or fromUTF8 to safely create arrays of words of the same type.


type Size
    = Bit32
    | Bit64

Size of a word.

Constructors

fromBytes : Size -> List Basics.Int -> Array Word

Convert a list of bytes to an array of words of the given size.

import Word.Hex as Hex

fromBytes Bit32 [ 0xDE, 0xAD, 0xBE, 0xEF ]
    |> Hex.fromWordArray
--> "deadbeef"

fromBytes Bit32
    [ 0xDE, 0xAD, 0xBE, 0xEF
    , 0x01, 0x23, 0x45, 0x67
    ]
    |> Hex.fromWordArray
--> "deadbeef01234567"

fromBytes Bit64
    [ 0xDE, 0xAD, 0xBE, 0xEF
    , 0x01, 0x23, 0x45, 0x67
    ]
    |> Hex.fromWordArray
--> "deadbeef01234567"

fromUTF8 : Size -> String -> Array Word

Convert a UTF8 string to an array of words of the given size.

import Word.Hex as Hex

fromUTF8 Bit32 "I ❤ UTF strings!" |> Hex.fromWordArray
--> [ "4920e29d"  -- 'I', ' ', 226, 157
--> , "a4205554"  -- 164, ' ', 'U', 'T'
--> , "46207374"  -- 'F', ' ', 's', 't'
--> , "72696e67"  -- 'r', 'i', 'n', 'g'
--> , "73210000"  -- 's', '!'
--> ] |> String.join ""

fromUTF8 Bit64 "I ❤ UTF strings!" |> Hex.fromWordArray
--> [ "4920e29d", "a4205554"  -- 'I', ' ', 226, 157, 164, ' ', 'U', 'T'
--> , "46207374", "72696e67"  -- 'F', ' ', 's', 't', 'r', 'i', 'n', 'g'
--> , "73210000", "00000000"  -- 's', '!'
--> ] |> String.join ""

zero : Size -> Word

The integer zero as a word of the given size.

Conversions

toBytes : Array Word -> List Basics.Int

Convert an array of words to a list of bytes.

import Array

[ W 0 ] |> Array.fromList |> toBytes
--> [ 0, 0, 0, 0 ]

[ D 0 0 ] |> Array.fromList |> toBytes
--> [ 0, 0, 0, 0, 0, 0, 0, 0 ]

[ W 16843010 ] |> Array.fromList |> toBytes
--> [ 1, 1, 1, 2 ]

Arithmetic

add : Word -> Word -> Word

Modulo adds two words of the same type.

import Word.Hex as Hex

add (W 0x80000000) (W 0x7FFFFFFF) |> Hex.fromWord
--> "ffffffff"

add (W 0x80000000) (W 0x80000003) |> Hex.fromWord
--> "00000003"

add (D 0 0xFFFFFFFF) (D 0 1) |> Hex.fromWord
--> "0000000100000000"

add (D 0xFFFFFFFF 0xFFFFFFFF) (D 0 2) |> Hex.fromWord
--> "0000000000000001"

add (W 0) (D 0 0)
--> Mismatch

Bitwise

and : Word -> Word -> Word

Bitwise and.

import Word.Hex as Hex

and
    (W 0xFF00FF00)
    (W 0xFFFF0000) |> Hex.fromWord
--> "ff000000"

and
    (D 0xFF00FF00 0xFFFF0000)
    (D 0xFFFF0000 0xFF00FF00) |> Hex.fromWord
--> "ff000000ff000000"

xor : Word -> Word -> Word

Bitwise xor.

import Word.Hex as Hex

Word.xor
    (W 0xFF00FF00)
    (W 0x00FFFF00) |> Hex.fromWord
--> "ffff0000"

Word.xor
    (D 0xFF00FF00 0x00FFFF00)
    (D 0x00FFFF00 0xFF00FF00) |> Hex.fromWord
--> "ffff0000ffff0000"

complement : Word -> Word

Bitwise complement.

import Word.Hex as Hex

complement
    (W 0x00FF00FF) |> Hex.fromWord
--> "ff00ff00"

complement
    (D 0x00FF00FF 0x00FF00FF) |> Hex.fromWord
--> "ff00ff00ff00ff00"

rotateLeftBy : Basics.Int -> Word -> Word

Rotate bits to the left by the given offset.

[[[[[[[[[https://en.wikipedia.org/wiki/Bitwise_operation#Rotate_no_carry](https://en.wikipedia.org/wiki/Bitwise_operation#Rotate_no_carry)](https://en.wikipedia.org/wiki/Bitwise_operation#Rotate_no_carry)](https://en.wikipedia.org/wiki/Bitwise_operation#Rotate_no_carry)](https://en.wikipedia.org/wiki/Bitwise_operation#Rotate_no_carry)](https://en.wikipedia.org/wiki/Bitwise_operation#Rotate_no_carry)](https://en.wikipedia.org/wiki/Bitwise_operation#Rotate_no_carry)](https://en.wikipedia.org/wiki/Bitwise_operation#Rotate_no_carry)](https://en.wikipedia.org/wiki/Bitwise_operation#Rotate_no_carry)](https://en.wikipedia.org/wiki/Bitwise_operation#Rotate_no_carry)

import Word.Hex as Hex

rotateLeftBy 4 (W 0xDEADBEEF) |> Hex.fromWord
--> "eadbeefd"

rotateLeftBy 4 (D 0xDDEEAADD 0xBBEEAAFF) |> Hex.fromWord
--> "deeaaddbbeeaaffd"

rotateLeftBy 7 Mismatch
--> Mismatch

rotateRightBy : Basics.Int -> Word -> Word

Rotate bits to the right by the given offset.

[[[[[[[[[https://en.wikipedia.org/wiki/Bitwise_operation#Rotate_no_carry](https://en.wikipedia.org/wiki/Bitwise_operation#Rotate_no_carry)](https://en.wikipedia.org/wiki/Bitwise_operation#Rotate_no_carry)](https://en.wikipedia.org/wiki/Bitwise_operation#Rotate_no_carry)](https://en.wikipedia.org/wiki/Bitwise_operation#Rotate_no_carry)](https://en.wikipedia.org/wiki/Bitwise_operation#Rotate_no_carry)](https://en.wikipedia.org/wiki/Bitwise_operation#Rotate_no_carry)](https://en.wikipedia.org/wiki/Bitwise_operation#Rotate_no_carry)](https://en.wikipedia.org/wiki/Bitwise_operation#Rotate_no_carry)](https://en.wikipedia.org/wiki/Bitwise_operation#Rotate_no_carry)

import Word.Hex as Hex

rotateRightBy 4 (W 0xDEADBEEF) |> Hex.fromWord
--> "fdeadbee"

rotateRightBy 4 (D 0xDDEEAADD 0xBBEEAAFF) |> Hex.fromWord
--> "fddeeaaddbbeeaaf"

rotateRightBy 7 Mismatch
--> Mismatch

shiftRightZfBy : Basics.Int -> Word -> Word

Shift bits to the right by a given offset, filling new bits with zeros.

[[[[[[[[[https://en.wikipedia.org/wiki/Bitwise_operation#Logical_shift](https://en.wikipedia.org/wiki/Bitwise_operation#Logical_shift)](https://en.wikipedia.org/wiki/Bitwise_operation#Logical_shift)](https://en.wikipedia.org/wiki/Bitwise_operation#Logical_shift)](https://en.wikipedia.org/wiki/Bitwise_operation#Logical_shift)](https://en.wikipedia.org/wiki/Bitwise_operation#Logical_shift)](https://en.wikipedia.org/wiki/Bitwise_operation#Logical_shift)](https://en.wikipedia.org/wiki/Bitwise_operation#Logical_shift)](https://en.wikipedia.org/wiki/Bitwise_operation#Logical_shift)](https://en.wikipedia.org/wiki/Bitwise_operation#Logical_shift)

import Word.Hex as Hex

shiftRightZfBy 9 (W 0xFFFF) |> Hex.fromWord
--> "0000007f"

shiftRightZfBy 32 (W 0xFFFF) |> Hex.fromWord
--> "00000000"

shiftRightZfBy 8 (D 0x01234567 0x89abcdef) |> Hex.fromWord
--> "000123456789abcd"

shiftRightZfBy 4 Mismatch
--> Mismatch

Misc

sizeInBytes : Size -> Basics.Int

Convert the given word size to a byte count.