// -*- go -*- // // Copyright (c) 2024 Markku Rossi // // All rights reserved. // // SHA-1 algorithm in QCL. This file is derived form the // src/crypto/sha1/sha1block.go file of Go 1.22.4. The original // copyright notice is as follows: // // Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package sha1 import ( "math/bits" ) const ( _K0 = 0x5A827999 _K1 = 0x6ED9EBA1 _K2 = 0x8F1BBCDC _K3 = 0xCA62C1D6 ) // Block implements the SHA-1 block step. func Block(p []byte, state [5]uint32) [5]uint32 { var w [16]uint32 if len(p) != chunk { panic("invalid input size") } h0, h1, h2, h3, h4 := state[0], state[1], state[2], state[3], state[4] // Can interlace the computation of w with the // rounds below if needed for speed. var i, j int32 for i = 0; i < 16; i++ { j = i * 4 w[i] = uint32(p[j])<<24 | uint32(p[j+1])<<16 | uint32(p[j+2])<<8 | uint32(p[j+3]) } a, b, c, d, e := h0, h1, h2, h3, h4 // Each of the four 20-iteration rounds // differs only in the computation of f and // the choice of K (_K0, _K1, etc). var f, t, tmp uint32 i = 0 for ; i < 16; i++ { f = b&c | (uint32(0xffffffff)^b)&d t = bits.RotateLeft32(a, 5) + f + e + w[i&0xf] + _K0 a, b, c, d, e = t, a, bits.RotateLeft32(b, 30), c, d } for ; i < 20; i++ { tmp = w[(i-3)&0xf] ^ w[(i-8)&0xf] ^ w[(i-14)&0xf] ^ w[(i)&0xf] w[i&0xf] = bits.RotateLeft32(tmp, 1) f = b&c | (0xffffffff^b)&d t = bits.RotateLeft32(a, 5) + f + e + w[i&0xf] + _K0 a, b, c, d, e = t, a, bits.RotateLeft32(b, 30), c, d } for ; i < 40; i++ { tmp = w[(i-3)&0xf] ^ w[(i-8)&0xf] ^ w[(i-14)&0xf] ^ w[(i)&0xf] w[i&0xf] = bits.RotateLeft32(tmp, 1) f = b ^ c ^ d t = bits.RotateLeft32(a, 5) + f + e + w[i&0xf] + _K1 a, b, c, d, e = t, a, bits.RotateLeft32(b, 30), c, d } for ; i < 60; i++ { tmp = w[(i-3)&0xf] ^ w[(i-8)&0xf] ^ w[(i-14)&0xf] ^ w[(i)&0xf] w[i&0xf] = bits.RotateLeft32(tmp, 1) f = ((b | c) & d) | (b & c) t = bits.RotateLeft32(a, 5) + f + e + w[i&0xf] + _K2 a, b, c, d, e = t, a, bits.RotateLeft32(b, 30), c, d } for ; i < 80; i++ { tmp = w[(i-3)&0xf] ^ w[(i-8)&0xf] ^ w[(i-14)&0xf] ^ w[(i)&0xf] w[i&0xf] = bits.RotateLeft32(tmp, 1) f = b ^ c ^ d t = bits.RotateLeft32(a, 5) + f + e + w[i&0xf] + _K3 a, b, c, d, e = t, a, bits.RotateLeft32(b, 30), c, d } h0 += a h1 += b h2 += c h3 += d h4 += e state[0] = h0 state[1] = h1 state[2] = h2 state[3] = h3 state[4] = h4 return state }