1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
// Copyright © 2021 rsiddharth <s@ricketyspace.net>
// SPDX-License-Identifier: ISC
package lib
// Converts padded messages bytes `pm` into 512-bit message blocks.
// Each 512-bit block is an array of 16 32-bit words.
// It's assumed bit length of `pm` is a multiple of 512.
func shaMessageBlocks(pm []byte) [][]uint32 {
// Break into 512-bit blocks
bs := BreakIntoBlocks(pm, 64)
mbs := make([][]uint32, 0) // Message blocks.
for i := 0; i < len(bs); i++ {
ws := make([]uint32, 0) // 32-bit words.
// Break 512-bit (64 bytes) into 32-bit words.
for j := 0; j < 64; j = j + 4 {
// Pack 4 bytes into a 32-bit word.
w := (uint32(bs[i][j])<<24 |
uint32(bs[i][j+1])<<16 |
uint32(bs[i][j+2])<<8 |
uint32(bs[i][j+3]))
ws = append(ws, w)
}
mbs = append(mbs, ws)
}
return mbs
}
// (a + b + ...) mod 2^32
func shaAdd(n ...uint32) uint32 {
sum := uint64(0)
for _, v := range n {
sum += uint64(v)
}
return uint32(sum & 0xFFFFFFFF)
}
// Circular Right Shift
func shaRotr(x uint32, n uint) uint32 {
return (x >> n) | (x << (32 - n))
}
// Circular Left Shift
func shaRotl(x uint32, n uint) uint32 {
return (x << n) | (x >> (32 - n))
}
// Returns Merkle–Damgård padding in bytes for length of mesage `l`
// bytes.
func MDPadding(l int) []byte {
l = l * 8 // msg size in bits
// Reckon value of `k`
k := 0
for ((l + 1 + k) % 512) != 448 {
k += 1
}
// Initialize padding bytes
pbs := make([]byte, 0)
// Add bit `1` as byte block.
pbs = append(pbs, 0x80)
f := 7 // unclaimed bits in last byte of `pbs`
// Add `k` bit `0`s
for i := 0; i < k; i++ {
if f == 0 {
pbs = append(pbs, 0x0)
f = 8
}
f = f - 1
}
// Add `l` in a 64 bit block in `pbs`
l64 := uint64(l)
b64 := make([]byte, 8) // last 64-bits
for i := 7; i >= 0; i-- {
// Get 8 last bits.
b64[i] = byte(l64 & 0xFF)
// Get rid of the last 8 bits.
l64 = l64 >> 8
}
pbs = append(pbs, b64...)
return pbs
}
|