Golang HashesThe new scripted languages such as Python and Node.js are convenient. But, unfortunately, they can be slow as they are scripted, and not compiled. Each time the scripted code is run, the scripting engine must then convert each line of code to the required machine level code. This makes the code much slower than compiled languages, and also less robust. Thus many applications in cryptography are written in C and C++, as they allow for fast execution and give low level access. Unfortunately it can be complex to compile programs, as we need binary libraries and link these in. The Go programming language has a similar code syntax to C/C++, but is small and efficient and allows access to low-level functions, such as as pointers. Go thus aims to "Code less, compile quicker, execute faster". |
Outline
We can use the Go programming language to implement compiled code for cryptography.
An outline of the Go code is:
package main import ( "crypto/rand" "golang.org/x/crypto/md4" "crypto/md5" "crypto/sha1" "crypto/sha256" "crypto/sha512" "golang.org/x/crypto/ripemd160" "golang.org/x/crypto/sha3" "golang.org/x/crypto/blake2b" "golang.org/x/crypto/scrypt" "golang.org/x/crypto/argon2" "golang.org/x/crypto/bcrypt" "fmt" ) type params struct { memory uint32 iterations uint32 parallelism uint8 saltLength uint32 keyLength uint32 } func generateRandomBytes(n uint32) ([]byte, error) { b := make([]byte, n) _, err := rand.Read(b) if err != nil { return nil, err } return b, nil } func main() { s := "abc" h1 := md4.New() h2 := md5.Sum([]byte(s)) h3 := sha1.Sum([]byte(s)) h4 := sha256.Sum256([]byte(s)) h5 := sha512.Sum512([]byte(s)) h6 := ripemd160.New() h7 := sha3.Sum256([]byte(s)) h8 := sha3.Sum512([]byte(s)) h9 := blake2b.Sum256([]byte(s)) h10 := blake2b.Sum512([]byte(s)) p := ¶ms{ memory: 64 * 1024, iterations: 1, parallelism: 1, saltLength: 16, keyLength: 32, } salt, err := generateRandomBytes(p.saltLength) h11 := argon2.IDKey([]byte(s), salt, p.iterations, p.memory, p.parallelism, p.keyLength) // Values are password, salt, N, r, p, key length h12, err := scrypt.Key([]byte(s), salt, 1<<15, 4, 1, 32) cost:=1 h13,err:=bcrypt.GenerateFromPassword([]byte(s), cost) h1.Write([]byte(s)) h6.Write([]byte(s)) fmt.Println("Input: ",s) fmt.Printf(" MD4: %x\n", h1.Sum(nil)) fmt.Printf("MD5: %x\n", h2) fmt.Printf("SHA-1: %x\n", h3) fmt.Printf("SHA-256: %x\n", h4) fmt.Printf("SHA-512: %x\n", h5) fmt.Printf("RIPEMD160: %x\n", h6.Sum(nil)) fmt.Printf("SHA-3 256: %x\n", h7) fmt.Printf("SHA-3 512: %x\n", h8) fmt.Printf("Blake2b 256-bit: %x\n", h9) fmt.Printf("Blake2b 512-bit: %x\n", h10) if (err= =nil) { fmt.Printf("Argon2: %x\n", h11) fmt.Printf("Scrypt: %x\n", h12) fmt.Printf("BCrypt: %s\n", h13) } }
In this case we integrate cryptography libraries using the Import() statement. These are imported in the src folder using Git with:
go get -u golang.org/x/crypto/...
The great advantage with Go is that it can be installed in most operating systems, and then can be compiled into an executable version [install]. We first create this code as file called "hash.go" and then compile with:
go build hash.go
In Microsoft Windows, this then creates an executable file named "hash.exe", and which can be run as a stand-alone program, and pass in an argument. A sample run is:
Input: abc MD4: a448017aaf21d8525fc10ae87aa6729d MD5: 900150983cd24fb0d6963f7d28e17f72 SHA-1: a9993e364706816aba3e25717850c26c9cd0d89d SHA-256: ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad SHA-512: ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f RIPEMD160: 8eb208f7e05d987a9b044a8e98c6b087f15a0bfc SHA-3 256: 3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532 SHA-3 512: b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0 Blake2b 256-bit: bddd813c634239723171ef3fee98579b94964e3bb1cb3e427262c8c068d52319 Blake2b 512-bit: ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923 Argon2: 685f42142b82c76041656f230ae7363e9b194f75da370040926169ec427499a6 Scrypt: 3fd40e6d8f98986a096b89809c30895417c78d7fad66c06fcda1366dbaec131f BCrypt: $2a$10$xvdP8jgbUwSGlKwCgprIZ.9BtbyB6AGtQQ8sfL1c391L0Jot/MaJ.
We can also run this from the Go file with:
c:\godir> go run hash.go fred Input: fred MD4: d6b5275b4f929f0a92fed52597d29b1d MD5: 570a90bfbf8c7eab5dc5d4e26832d5b1 SHA-1: 31017a722665e4afce586950f42944a6d331dabf SHA-256: d0cfc2e5319b82cdc71a33873e826c93d7ee11363f8ac91c4fa3a2cfcd2286e5 SHA-512: 3566c33c35c59ba2587bac2a81526cf33ea0928111ed9e1616aa43fcffbc3f5d07e058c 80898cd286095b7587ad5edd3511fd943fd7d7743b1ded724262026f3 RIPEMD160: d518c29118fca3f5fbafd9efa17db154930fcced SHA-3 256: 901e5b95a7c6f4c25f1dbb31931585a1aac6cac21eb1f09a39411f5ba4e710d6 SHA-3 512: 9d15efc1b71e0143a4daad34d5bb2e97d4968d80269e49c633aac69cc13d990b25295 685eacb5b29eb584a1f6dd92a8e91e257c0c493a869310bee0b8a2ef440 Blake2b 256-bit: 3e5f32e0066871d68a6713be8274fee3a079971d0ceaa44878f58beb0936a33 9 Blake2b 512-bit: 817bdde172952d439c9ccb1a4d91476c93cd4578038715f139d9095a9f7a180 26463d67e3c666733a8e4e733195414e7888631057b3857418f51a61848467d10 Argon2: 0bbde4e32ced1fc444a392ebd2888c42e0cd4fd8610bf2acb9323f13ce29b1c5 Scrypt: dc87fe00fb543f327ba44aaa579bbde6d94e2b33c151339b001e91067d3b6927 BCrypt: $2a$10$Uqe7dk52iIJDRmGAnSCXy.ejaPyyhsPqmek8dwrvh4DSedhCNEnmi