chore: go mod tidy / vendor / make deps

This commit is contained in:
2025-10-02 08:25:31 +02:00
parent 1c10e64c58
commit d63a1c28ea
505 changed files with 34448 additions and 35285 deletions

View File

@ -1,4 +1,4 @@
FROM golang:1.24@sha256:20a022e5112a144aa7b7aeb3f22ebf2cdaefcc4aac0d64e8deeee8cdc18b9c0f
FROM golang:1.24@sha256:14fd8a55e59a560704e5fc44970b301d00d344e45d6b914dda228e09f359a088
ENV GOOS=linux
ENV GOARCH=arm

View File

@ -1,4 +1,4 @@
FROM golang:1.24@sha256:20a022e5112a144aa7b7aeb3f22ebf2cdaefcc4aac0d64e8deeee8cdc18b9c0f
FROM golang:1.24@sha256:14fd8a55e59a560704e5fc44970b301d00d344e45d6b914dda228e09f359a088
ENV GOOS=linux
ENV GOARCH=arm64

View File

@ -31,9 +31,6 @@ build-nocgo:
# Run cross-compilation to assure supported architectures.
cross-build: build-arm build-arm64 build-nocgo
generate:
go generate -x ./...
verify: generate
verify:
git diff --exit-code
go vet ./...

View File

@ -6,8 +6,7 @@ collision attacks.
The `cgo/lib` code is a carbon copy of the [original code], based on
the award winning [white paper] by Marc Stevens.
The Go implementation is largely based off Go's generic sha1.
At present no SIMD optimisations have been implemented.
The Go and native implementations are largely based off upstream Go.
## Usage

View File

@ -20,8 +20,6 @@ import (
shared "github.com/pjbgf/sha1cd/internal"
)
//go:generate go run -C asm . -out ../sha1cdblock_amd64.s -pkg $GOPACKAGE
func init() {
crypto.RegisterHash(crypto.SHA1, New)
}
@ -40,8 +38,7 @@ type digest struct {
len uint64
// col defines whether a collision has been found.
col bool
blockFunc func(dig *digest, p []byte)
col bool
}
func (d *digest) MarshalBinary() ([]byte, error) {
@ -101,7 +98,7 @@ func (d *digest) UnmarshalBinary(b []byte) error {
func consumeUint64(b []byte) ([]byte, uint64) {
_ = b[7]
x := uint64(b[7]) | uint64(b[6])<<8 | uint64(b[shared.WordBuffers])<<16 | uint64(b[4])<<24 |
x := uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
return b[8:], x
}
@ -128,21 +125,9 @@ func (d *digest) Reset() {
// implements encoding.BinaryMarshaler and encoding.BinaryUnmarshaler to
// marshal and unmarshal the internal state of the hash.
func New() hash.Hash {
d := new(digest)
d.blockFunc = block
var d digest
d.Reset()
return d
}
// NewGeneric is equivalent to New but uses the Go generic implementation,
// avoiding any processor-specific optimizations.
func NewGeneric() hash.Hash {
d := new(digest)
d.blockFunc = blockGeneric
d.Reset()
return d
return &d
}
func (d *digest) Size() int { return Size }
@ -160,14 +145,14 @@ func (d *digest) Write(p []byte) (nn int, err error) {
n := copy(d.x[d.nx:], p)
d.nx += n
if d.nx == shared.Chunk {
d.blockFunc(d, d.x[:])
block(d, d.x[:])
d.nx = 0
}
p = p[n:]
}
if len(p) >= shared.Chunk {
n := len(p) &^ (shared.Chunk - 1)
d.blockFunc(d, p[:n])
block(d, p[:n])
p = p[n:]
}
if len(p) > 0 {
@ -186,18 +171,20 @@ func (d *digest) Sum(in []byte) []byte {
func (d *digest) checkSum() [Size]byte {
len := d.len
// Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
var tmp [64]byte
var tmp [64 + 8]byte
tmp[0] = 0x80
var t uint64
if len%64 < 56 {
d.Write(tmp[0 : 56-len%64])
t = 56 - len%64
} else {
d.Write(tmp[0 : 64+56-len%64])
t = 64 + 56 - len%64
}
// Length in bits.
len <<= 3
binary.BigEndian.PutUint64(tmp[:], len)
d.Write(tmp[0:8])
padlen := tmp[:t+8]
binary.BigEndian.PutUint64(tmp[t:], len)
d.Write(padlen)
if d.nx != 0 {
panic("d.nx != 0")
@ -216,7 +203,8 @@ func (d *digest) checkSum() [Size]byte {
// Sum returns the SHA-1 checksum of the data.
func Sum(data []byte) ([Size]byte, bool) {
d := New().(*digest)
var d digest
d.Reset()
d.Write(data)
return d.checkSum(), d.col
}

View File

@ -4,39 +4,47 @@
package sha1cd
import (
"math"
"unsafe"
"runtime"
"github.com/klauspost/cpuid/v2"
shared "github.com/pjbgf/sha1cd/internal"
)
// blockAMD64 hashes the message p into the current state in dig.
var hasSHANI = (runtime.GOARCH == "amd64" &&
cpuid.CPU.Supports(cpuid.AVX) &&
cpuid.CPU.Supports(cpuid.SHA) &&
cpuid.CPU.Supports(cpuid.SSE3) &&
cpuid.CPU.Supports(cpuid.SSE4))
// blockAMD64 hashes the message p into the current state in h.
// Both m1 and cs are used to store intermediate results which are used by the collision detection logic.
//
//go:noescape
func blockAMD64(dig *digest, p sliceHeader, m1 []uint32, cs [][5]uint32)
func blockAMD64(h []uint32, p []byte, m1 []uint32, cs [][5]uint32)
func block(dig *digest, p []byte) {
if forceGeneric || !hasSHANI {
blockGeneric(dig, p)
return
}
m1 := [shared.Rounds]uint32{}
cs := [shared.PreStepState][shared.WordBuffers]uint32{}
for len(p) >= shared.Chunk {
// Only send a block to be processed, as the collission detection
// works on a block by block basis.
ips := sliceHeader{
base: uintptr(unsafe.Pointer(&p[0])),
len: int(math.Min(float64(len(p)), float64(shared.Chunk))),
cap: shared.Chunk,
}
// The assembly code only supports processing a block at a time,
// so adjust the chunk accordingly.
chunk := p[:shared.Chunk]
blockAMD64(dig, ips, m1[:], cs[:])
blockAMD64(dig.h[:], chunk, m1[:], cs[:])
rectifyCompressionState(m1, &cs)
col := checkCollision(m1, cs, dig.h)
if col {
dig.col = true
blockAMD64(dig, ips, m1[:], cs[:])
blockAMD64(dig, ips, m1[:], cs[:])
blockAMD64(dig.h[:], chunk, m1[:], cs[:])
blockAMD64(dig.h[:], chunk, m1[:], cs[:])
}
p = p[shared.Chunk:]

File diff suppressed because it is too large Load Diff

View File

@ -4,39 +4,43 @@
package sha1cd
import (
"math"
"unsafe"
"runtime"
"github.com/klauspost/cpuid/v2"
shared "github.com/pjbgf/sha1cd/internal"
)
// blockARM64 hashes the message p into the current state in dig.
var hasSHA1 = (runtime.GOARCH == "arm64" && cpuid.CPU.Supports(cpuid.SHA1))
// blockARM64 hashes the message p into the current state in h.
// Both m1 and cs are used to store intermediate results which are used by the collision detection logic.
//
//go:noescape
func blockARM64(dig *digest, p sliceHeader, m1 []uint32, cs [][5]uint32)
func blockARM64(h []uint32, p []byte, m1 []uint32, cs [][5]uint32)
func block(dig *digest, p []byte) {
if forceGeneric || !hasSHA1 {
blockGeneric(dig, p)
return
}
m1 := [shared.Rounds]uint32{}
cs := [shared.PreStepState][shared.WordBuffers]uint32{}
for len(p) >= shared.Chunk {
// Only send a block to be processed, as the collission detection
// works on a block by block basis.
ips := sliceHeader{
base: uintptr(unsafe.Pointer(&p[0])),
len: int(math.Min(float64(len(p)), float64(shared.Chunk))),
cap: shared.Chunk,
}
// The assembly code only supports processing a block at a time,
// so adjust the chunk accordingly.
chunk := p[:shared.Chunk]
blockARM64(dig, ips, m1[:], cs[:])
blockARM64(dig.h[:], chunk, m1[:], cs[:])
rectifyCompressionState(m1, &cs)
col := checkCollision(m1, cs, dig.h)
if col {
dig.col = true
blockARM64(dig, ips, m1[:], cs[:])
blockARM64(dig, ips, m1[:], cs[:])
blockARM64(dig.h[:], chunk, m1[:], cs[:])
blockARM64(dig.h[:], chunk, m1[:], cs[:])
}
p = p[shared.Chunk:]

View File

@ -2,243 +2,248 @@
#include "textflag.h"
#define RoundConst0 $1518500249 // 0x5A827999
#define RoundConst1 $1859775393 // 0x6ED9EBA1
#define RoundConst2 $2400959708 // 0x8F1BBCDC
#define RoundConst3 $3395469782 // 0xCA62C1D6
// License information for the original SHA1 arm64 implemention:
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found at:
// - https://github.com/golang/go/blob/master/LICENSE
//
// Reference implementations:
// - https://github.com/noloader/SHA-Intrinsics/blob/master/sha1-arm.c
// - https://github.com/golang/go/blob/master/src/crypto/sha1/sha1block_arm64.s
// FUNC1 f = (b & c) | ((~b) & d)
#define FUNC1(b, c, d) \
MOVW d, R15; \
EORW c, R15; \
ANDW b, R15; \
EORW d, R15
#define HASHUPDATECHOOSE \
SHA1C V16.S4, V1, V2 \
SHA1H V3, V1 \
VMOV V2.B16, V3.B16
// FUNC2 f = b ^ c ^ d
#define FUNC2(b, c, d) \
MOVW b, R15; \
EORW c, R15; \
EORW d, R15
#define HASHUPDATEPARITY \
SHA1P V16.S4, V1, V2 \
SHA1H V3, V1 \
VMOV V2.B16, V3.B16
// FUNC3 f = (b & c) | (b & d) | (c & d)
#define FUNC3(b, c, d) \
MOVW b, R27; \
ORR c, R27, R27; \
ANDW d, R27, R27; \
MOVW b, R15; \
ANDW c, R15, R15; \
ORR R27, R15, R15
#define HASHUPDATEMAJ \
SHA1M V16.S4, V1, V2 \
SHA1H V3, V1 \
VMOV V2.B16, V3.B16
#define FUNC4(b, c, d) FUNC2(b, c, d)
#define MIX(a, b, c, d, e, k) \
RORW $2, b, b; \
ADDW R15, e, e; \
MOVW a, R27; \
RORW $27, R27, R27; \
MOVW k, R19; \
ADDW R19, e, e; \
ADDW R9, e, e; \
ADDW R27, e, e
// func blockARM64(h []uint32, p []byte, m1 []uint32, cs [][5]uint32)
TEXT ·blockARM64(SB), NOSPLIT, $80-96
MOVD h_base+0(FP), R0
MOVD p_base+24(FP), R1
MOVD p_len+32(FP), R2
MOVD m1_base+48(FP), R3
MOVD cs_base+72(FP), R4
#define LOAD(index) \
MOVWU (index*4)(R16), R9; \
REVW R9, R9; \
MOVW R9, (index*4)(RSP)
LSR $6, R2, R2
LSL $6, R2, R2
ADD R16, R2, R21
#define LOADCS(a, b, c, d, e, index) \
MOVD cs_base+56(FP), R27; \
MOVW a, ((index*20))(R27); \
MOVW b, ((index*20)+4)(R27); \
MOVW c, ((index*20)+8)(R27); \
MOVW d, ((index*20)+12)(R27); \
MOVW e, ((index*20)+16)(R27)
#define SHUFFLE(index) \
MOVW ((index&0xf)*4)(RSP), R9; \
MOVW (((index-3)&0xf)*4)(RSP), R20; \
EORW R20, R9; \
MOVW (((index-8)&0xf)*4)(RSP), R20; \
EORW R20, R9; \
MOVW (((index-14)&0xf)*4)(RSP), R20; \
EORW R20, R9; \
RORW $31, R9, R9; \
MOVW R9, ((index&0xf)*4)(RSP)
// LOADM1 stores message word to m1 array.
#define LOADM1(index) \
MOVD m1_base+32(FP), R27; \
MOVW ((index&0xf)*4)(RSP), R9; \
MOVW R9, (index*4)(R27)
#define ROUND1(a, b, c, d, e, index) \
LOAD(index); \
FUNC1(b, c, d); \
MIX(a, b, c, d, e, RoundConst0); \
LOADM1(index)
#define ROUND1x(a, b, c, d, e, index) \
SHUFFLE(index); \
FUNC1(b, c, d); \
MIX(a, b, c, d, e, RoundConst0); \
LOADM1(index)
#define ROUND2(a, b, c, d, e, index) \
SHUFFLE(index); \
FUNC2(b, c, d); \
MIX(a, b, c, d, e, RoundConst1); \
LOADM1(index)
#define ROUND3(a, b, c, d, e, index) \
SHUFFLE(index); \
FUNC3(b, c, d); \
MIX(a, b, c, d, e, RoundConst2); \
LOADM1(index)
#define ROUND4(a, b, c, d, e, index) \
SHUFFLE(index); \
FUNC4(b, c, d); \
MIX(a, b, c, d, e, RoundConst3); \
LOADM1(index)
// func blockARM64(dig *digest, p []byte, m1 []uint32, cs [][5]uint32)
TEXT ·blockARM64(SB), NOSPLIT, $64-80
MOVD dig+0(FP), R8
MOVD p_base+8(FP), R16
MOVD p_len+16(FP), R10
LSR $6, R10, R10
LSL $6, R10, R10
ADD R16, R10, R21
// Load h0-h4 into R1R5.
MOVW (R8), R1 // R1 = h0
MOVW 4(R8), R2 // R2 = h1
MOVW 8(R8), R3 // R3 = h2
MOVW 12(R8), R4 // R4 = h3
MOVW 16(R8), R5 // R5 = h4
VLD1.P 16(R0), [V0.S4]
FMOVS (R0), F20
SUB $16, R0, R0
loop:
// len(p) >= chunk
CMP R16, R21
BLS end
CMP R16, R21
BLS end
// Initialize registers a, b, c, d, e.
MOVW R1, R10
MOVW R2, R11
MOVW R3, R12
MOVW R4, R13
MOVW R5, R14
// Load block (p) into 16-bytes vectors.
VLD1.P 16(R1), [V4.B16]
VLD1.P 16(R1), [V5.B16]
VLD1.P 16(R1), [V6.B16]
VLD1.P 16(R1), [V7.B16]
// Load K constants to V19
MOVD $·sha1Ks(SB), R22
VLD1 (R22), [V19.S4]
VMOV V0.B16, V2.B16
VMOV V20.S[0], V1
VMOV V2.B16, V3.B16
VDUP V19.S[0], V17.S4
// Little Endian
VREV32 V4.B16, V4.B16
VREV32 V5.B16, V5.B16
VREV32 V6.B16, V6.B16
VREV32 V7.B16, V7.B16
// LOAD M1 rounds 0-15
VST1.P [V4.S4], (R3)
VST1.P [V5.S4], (R3)
VST1.P [V6.S4], (R3)
VST1.P [V7.S4], (R3)
// ROUND1 (steps 0-15)
LOADCS(R10, R11, R12, R13, R14, 0)
ROUND1(R10, R11, R12, R13, R14, 0)
ROUND1(R14, R10, R11, R12, R13, 1)
ROUND1(R13, R14, R10, R11, R12, 2)
ROUND1(R12, R13, R14, R10, R11, 3)
ROUND1(R11, R12, R13, R14, R10, 4)
ROUND1(R10, R11, R12, R13, R14, 5)
ROUND1(R14, R10, R11, R12, R13, 6)
ROUND1(R13, R14, R10, R11, R12, 7)
ROUND1(R12, R13, R14, R10, R11, 8)
ROUND1(R11, R12, R13, R14, R10, 9)
ROUND1(R10, R11, R12, R13, R14, 10)
ROUND1(R14, R10, R11, R12, R13, 11)
ROUND1(R13, R14, R10, R11, R12, 12)
ROUND1(R12, R13, R14, R10, R11, 13)
ROUND1(R11, R12, R13, R14, R10, 14)
ROUND1(R10, R11, R12, R13, R14, 15)
// LOAD CS 0
VST1.P [V0.S4], (R4) // ABCD pre-round 0
VST1.P V1.S[0], 4(R4) // E pre-round 0
// ROUND1x (steps 16-19) - same as ROUND1 but with no data load.
ROUND1x(R14, R10, R11, R12, R13, 16)
ROUND1x(R13, R14, R10, R11, R12, 17)
ROUND1x(R12, R13, R14, R10, R11, 18)
ROUND1x(R11, R12, R13, R14, R10, 19)
// Rounds 0-3
VDUP V19.S[1], V18.S4
VADD V17.S4, V4.S4, V16.S4
SHA1SU0 V6.S4, V5.S4, V4.S4
HASHUPDATECHOOSE
SHA1SU1 V7.S4, V4.S4
// ROUND2 (steps 20-39)
ROUND2(R10, R11, R12, R13, R14, 20)
ROUND2(R14, R10, R11, R12, R13, 21)
ROUND2(R13, R14, R10, R11, R12, 22)
ROUND2(R12, R13, R14, R10, R11, 23)
ROUND2(R11, R12, R13, R14, R10, 24)
ROUND2(R10, R11, R12, R13, R14, 25)
ROUND2(R14, R10, R11, R12, R13, 26)
ROUND2(R13, R14, R10, R11, R12, 27)
ROUND2(R12, R13, R14, R10, R11, 28)
ROUND2(R11, R12, R13, R14, R10, 29)
ROUND2(R10, R11, R12, R13, R14, 30)
ROUND2(R14, R10, R11, R12, R13, 31)
ROUND2(R13, R14, R10, R11, R12, 32)
ROUND2(R12, R13, R14, R10, R11, 33)
ROUND2(R11, R12, R13, R14, R10, 34)
ROUND2(R10, R11, R12, R13, R14, 35)
ROUND2(R14, R10, R11, R12, R13, 36)
ROUND2(R13, R14, R10, R11, R12, 37)
ROUND2(R12, R13, R14, R10, R11, 38)
ROUND2(R11, R12, R13, R14, R10, 39)
// Rounds 4-7
VADD V17.S4, V5.S4, V16.S4
SHA1SU0 V7.S4, V6.S4, V5.S4
HASHUPDATECHOOSE
SHA1SU1 V4.S4, V5.S4
// LOAD M1 rounds 16-19
VST1.P [V4.S4], (R3)
// ROUND3 (steps 40-59)
ROUND3(R10, R11, R12, R13, R14, 40)
ROUND3(R14, R10, R11, R12, R13, 41)
ROUND3(R13, R14, R10, R11, R12, 42)
ROUND3(R12, R13, R14, R10, R11, 43)
ROUND3(R11, R12, R13, R14, R10, 44)
ROUND3(R10, R11, R12, R13, R14, 45)
ROUND3(R14, R10, R11, R12, R13, 46)
ROUND3(R13, R14, R10, R11, R12, 47)
ROUND3(R12, R13, R14, R10, R11, 48)
ROUND3(R11, R12, R13, R14, R10, 49)
ROUND3(R10, R11, R12, R13, R14, 50)
ROUND3(R14, R10, R11, R12, R13, 51)
ROUND3(R13, R14, R10, R11, R12, 52)
ROUND3(R12, R13, R14, R10, R11, 53)
ROUND3(R11, R12, R13, R14, R10, 54)
ROUND3(R10, R11, R12, R13, R14, 55)
ROUND3(R14, R10, R11, R12, R13, 56)
ROUND3(R13, R14, R10, R11, R12, 57)
// Rounds 8-11
VADD V17.S4, V6.S4, V16.S4
SHA1SU0 V4.S4, V7.S4, V6.S4
HASHUPDATECHOOSE
SHA1SU1 V5.S4, V6.S4
// LOAD M1 rounds 20-23
VST1.P [V5.S4], (R3)
LOADCS(R12, R13, R14, R10, R11, 1)
ROUND3(R12, R13, R14, R10, R11, 58)
ROUND3(R11, R12, R13, R14, R10, 59)
// Rounds 12-15
VADD V17.S4, V7.S4, V16.S4
SHA1SU0 V5.S4, V4.S4, V7.S4
HASHUPDATECHOOSE
SHA1SU1 V6.S4, V7.S4
// LOAD M1 rounds 24-27
VST1.P [V6.S4], (R3)
// ROUND4 (steps 60-79)
ROUND4(R10, R11, R12, R13, R14, 60)
ROUND4(R14, R10, R11, R12, R13, 61)
ROUND4(R13, R14, R10, R11, R12, 62)
ROUND4(R12, R13, R14, R10, R11, 63)
ROUND4(R11, R12, R13, R14, R10, 64)
// Rounds 16-19
VADD V17.S4, V4.S4, V16.S4
SHA1SU0 V6.S4, V5.S4, V4.S4
HASHUPDATECHOOSE
SHA1SU1 V7.S4, V4.S4
// LOAD M1 rounds 28-31
VST1.P [V7.S4], (R3)
LOADCS(R10, R11, R12, R13, R14, 2)
ROUND4(R10, R11, R12, R13, R14, 65)
ROUND4(R14, R10, R11, R12, R13, 66)
ROUND4(R13, R14, R10, R11, R12, 67)
ROUND4(R12, R13, R14, R10, R11, 68)
ROUND4(R11, R12, R13, R14, R10, 69)
ROUND4(R10, R11, R12, R13, R14, 70)
ROUND4(R14, R10, R11, R12, R13, 71)
ROUND4(R13, R14, R10, R11, R12, 72)
ROUND4(R12, R13, R14, R10, R11, 73)
ROUND4(R11, R12, R13, R14, R10, 74)
ROUND4(R10, R11, R12, R13, R14, 75)
ROUND4(R14, R10, R11, R12, R13, 76)
ROUND4(R13, R14, R10, R11, R12, 77)
ROUND4(R12, R13, R14, R10, R11, 78)
ROUND4(R11, R12, R13, R14, R10, 79)
// Rounds 20-23
VDUP V19.S[2], V17.S4
VADD V18.S4, V5.S4, V16.S4
SHA1SU0 V7.S4, V6.S4, V5.S4
HASHUPDATEPARITY
SHA1SU1 V4.S4, V5.S4
// LOAD M1 rounds 32-35
VST1.P [V4.S4], (R3)
// Add registers to temp hash.
ADDW R10, R1, R1
ADDW R11, R2, R2
ADDW R12, R3, R3
ADDW R13, R4, R4
ADDW R14, R5, R5
// Rounds 24-27
VADD V18.S4, V6.S4, V16.S4
SHA1SU0 V4.S4, V7.S4, V6.S4
HASHUPDATEPARITY
SHA1SU1 V5.S4, V6.S4
// LOAD M1 rounds 36-39
VST1.P [V5.S4], (R3)
ADD $64, R16, R16
B loop
// Rounds 28-31
VADD V18.S4, V7.S4, V16.S4
SHA1SU0 V5.S4, V4.S4, V7.S4
HASHUPDATEPARITY
SHA1SU1 V6.S4, V7.S4
// LOAD M1 rounds 40-43
VST1.P [V6.S4], (R3)
// Rounds 32-35
VADD V18.S4, V4.S4, V16.S4
SHA1SU0 V6.S4, V5.S4, V4.S4
HASHUPDATEPARITY
SHA1SU1 V7.S4, V4.S4
// LOAD M1 rounds 44-47
VST1.P [V7.S4], (R3)
// Rounds 36-39
VADD V18.S4, V5.S4, V16.S4
SHA1SU0 V7.S4, V6.S4, V5.S4
HASHUPDATEPARITY
SHA1SU1 V4.S4, V5.S4
// LOAD M1 rounds 48-51
VST1.P [V4.S4], (R3)
// Rounds 44-47
VDUP V19.S[3], V18.S4
VADD V17.S4, V6.S4, V16.S4
SHA1SU0 V4.S4, V7.S4, V6.S4
HASHUPDATEMAJ
SHA1SU1 V5.S4, V6.S4
// LOAD M1 rounds 52-55
VST1.P [V5.S4], (R3)
// Rounds 44-47
VADD V17.S4, V7.S4, V16.S4
SHA1SU0 V5.S4, V4.S4, V7.S4
HASHUPDATEMAJ
SHA1SU1 V6.S4, V7.S4
// LOAD M1 rounds 56-59
VST1.P [V6.S4], (R3)
// Rounds 48-51
VADD V17.S4, V4.S4, V16.S4
SHA1SU0 V6.S4, V5.S4, V4.S4
HASHUPDATEMAJ
SHA1SU1 V7.S4, V4.S4
// LOAD M1 rounds 60-63
VST1.P [V7.S4], (R3)
// Rounds 52-55
VADD V17.S4, V5.S4, V16.S4
SHA1SU0 V7.S4, V6.S4, V5.S4
HASHUPDATEMAJ
SHA1SU1 V4.S4, V5.S4
// LOAD CS 58
VST1.P [V3.S4], (R4) // ABCD pre-round 56
VST1.P V1.S[0], 4(R4) // E pre-round 56
// Rounds 56-59
VADD V17.S4, V6.S4, V16.S4
SHA1SU0 V4.S4, V7.S4, V6.S4
HASHUPDATEMAJ
SHA1SU1 V5.S4, V6.S4
// Rounds 60-63
VADD V18.S4, V7.S4, V16.S4
SHA1SU0 V5.S4, V4.S4, V7.S4
HASHUPDATEPARITY
SHA1SU1 V6.S4, V7.S4
// LOAD CS 65
VST1.P [V3.S4], (R4) // ABCD pre-round 64
VST1.P V1.S[0], 4(R4) // E pre-round 64
// Rounds 64-67
VADD V18.S4, V4.S4, V16.S4
HASHUPDATEPARITY
// LOAD M1 rounds 68-79
VST1.P [V4.S4], (R3)
VST1.P [V5.S4], (R3)
VST1.P [V6.S4], (R3)
VST1.P [V7.S4], (R3)
// Rounds 68-71
VADD V18.S4, V5.S4, V16.S4
HASHUPDATEPARITY
// Rounds 72-75
VADD V18.S4, V6.S4, V16.S4
HASHUPDATEPARITY
// Rounds 76-79
VADD V18.S4, V7.S4, V16.S4
HASHUPDATEPARITY
// Add working registers to hash state.
VADD V2.S4, V0.S4, V0.S4
VADD V1.S4, V20.S4, V20.S4
end:
MOVW R1, (R8)
MOVW R2, 4(R8)
MOVW R3, 8(R8)
MOVW R4, 12(R8)
MOVW R5, 16(R8)
// Update h with final hash values.
VST1.P [V0.S4], (R0)
FMOVS F20, (R0)
RET
DATA ·sha1Ks+0(SB)/4, $0x5A827999 // K0
DATA ·sha1Ks+4(SB)/4, $0x6ED9EBA1 // K1
DATA ·sha1Ks+8(SB)/4, $0x8F1BBCDC // K2
DATA ·sha1Ks+12(SB)/4, $0xCA62C1D6 // K3
GLOBL ·sha1Ks(SB), RODATA, $16

View File

@ -1,11 +0,0 @@
//go:build (!amd64 || !arm64) && !noasm
// +build !amd64 !arm64
// +build !noasm
package sha1cd
type sliceHeader struct {
base uintptr
len int
cap int
}

View File

@ -15,6 +15,8 @@ import (
"github.com/pjbgf/sha1cd/ubc"
)
var forceGeneric bool
// blockGeneric is a portable, pure Go version of the SHA-1 block step.
// It's used by sha1block_generic.go and tests.
func blockGeneric(dig *digest, p []byte) {
@ -139,11 +141,12 @@ func blockGeneric(dig *digest, p []byte) {
dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4] = h0, h1, h2, h3, h4
}
//go:noinline
func checkCollision(
m1 [shared.Rounds]uint32,
cs [shared.PreStepState][shared.WordBuffers]uint32,
state [shared.WordBuffers]uint32) bool {
h [shared.WordBuffers]uint32,
) bool {
if mask := ubc.CalculateDvMask(m1); mask != 0 {
dvs := ubc.SHA1_dvs()
@ -167,7 +170,7 @@ func checkCollision(
// ubc's DM prior to the SHA recompression step.
m1, dvs[i].Dm,
csState,
state)
h)
if col {
return true
@ -178,6 +181,7 @@ func checkCollision(
return false
}
//go:nosplit
func hasCollided(step uint32, m1, dm [shared.Rounds]uint32,
state [shared.WordBuffers]uint32, h [shared.WordBuffers]uint32) bool {
// Intermediary Hash Value.
@ -266,3 +270,42 @@ func hasCollided(step uint32, m1, dm [shared.Rounds]uint32,
return false
}
// rectifyCompressionState fixes the compression state when using the
// SIMD implementations.
//
// Due to the way that hardware acceleration works, the rounds
// are executed 4 at a time. Therefore, the state for cs58 and cs65
// are not available directly through the assembly logic. The states
// returned are for cs56 and cs64. This function updates indexes 1 and 2
// of cs to contain the respective CS values for rounds 58 and 65.
//
//go:nosplit
func rectifyCompressionState(
m1 [shared.Rounds]uint32,
cs *[shared.PreStepState][shared.WordBuffers]uint32,
) {
if cs == nil {
return
}
func3 := func(state [shared.WordBuffers]uint32, i int) [shared.WordBuffers]uint32 {
a, b, c, d, e := state[0], state[1], state[2], state[3], state[4]
f := ((b | c) & d) | (b & c)
t := bits.RotateLeft32(a, 5) + f + e + m1[i] + shared.K2
a, b, c, d, e = t, a, bits.RotateLeft32(b, 30), c, d
return [shared.WordBuffers]uint32{a, b, c, d, e}
}
func4 := func(state [shared.WordBuffers]uint32, i int) [shared.WordBuffers]uint32 {
a, b, c, d, e := state[0], state[1], state[2], state[3], state[4]
f := b ^ c ^ d
t := bits.RotateLeft32(a, 5) + f + e + m1[i] + shared.K3
a, b, c, d, e = t, a, bits.RotateLeft32(b, 30), c, d
return [shared.WordBuffers]uint32{a, b, c, d, e}
}
cs57 := func3(cs[1], 56)
cs[1] = func3(cs57, 57)
cs[2] = func4(cs[2], 64)
}

View File

@ -1,5 +1,4 @@
//go:build (!amd64 && !arm64) || noasm || !gc
// +build !amd64,!arm64 noasm !gc
//go:build (!amd64 && !arm64) || noasm
package sha1cd

View File

@ -2,4 +2,372 @@
// Unavoidable Bit Conditions that arise from crypto analysis attacks.
package ubc
//go:generate go run -C asm . -out ../ubc_amd64.s -pkg $GOPACKAGE
// Based on the C implementation from Marc Stevens and Dan Shumow.
// https://github.com/cr-marcstevens/sha1collisiondetection
type DvInfo struct {
// DvType, DvK and DvB define the DV: I(K,B) or II(K,B) (see the paper).
// https://marc-stevens.nl/research/papers/C13-S.pdf
DvType uint32
DvK uint32
DvB uint32
// TestT is the step to do the recompression from for collision detection.
TestT uint32
// MaskI and MaskB define the bit to check for each DV in the dvmask returned by ubc_check.
MaskI uint32
MaskB uint32
// Dm is the expanded message block XOR-difference defined by the DV.
Dm [80]uint32
}
// CalculateDvMask takes as input an expanded message block and
// verifies the unavoidable bitconditions for all listed DVs. It returns
// a dvmask where each bit belonging to a DV is set if all unavoidable
// bitconditions for that DV have been met.
//
//go:nosplit
func CalculateDvMask(W [80]uint32) uint32 {
mask := uint32(0xFFFFFFFF)
mask &= (((((W[44] ^ W[45]) >> 29) & 1) - 1) | ^(DV_I_48_0_bit | DV_I_51_0_bit | DV_I_52_0_bit | DV_II_45_0_bit | DV_II_46_0_bit | DV_II_50_0_bit | DV_II_51_0_bit))
mask &= (((((W[49] ^ W[50]) >> 29) & 1) - 1) | ^(DV_I_46_0_bit | DV_II_45_0_bit | DV_II_50_0_bit | DV_II_51_0_bit | DV_II_55_0_bit | DV_II_56_0_bit))
mask &= (((((W[48] ^ W[49]) >> 29) & 1) - 1) | ^(DV_I_45_0_bit | DV_I_52_0_bit | DV_II_49_0_bit | DV_II_50_0_bit | DV_II_54_0_bit | DV_II_55_0_bit))
mask &= ((((W[47] ^ (W[50] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_I_47_0_bit | DV_I_49_0_bit | DV_I_51_0_bit | DV_II_45_0_bit | DV_II_51_0_bit | DV_II_56_0_bit))
mask &= (((((W[47] ^ W[48]) >> 29) & 1) - 1) | ^(DV_I_44_0_bit | DV_I_51_0_bit | DV_II_48_0_bit | DV_II_49_0_bit | DV_II_53_0_bit | DV_II_54_0_bit))
mask &= (((((W[46] >> 4) ^ (W[49] >> 29)) & 1) - 1) | ^(DV_I_46_0_bit | DV_I_48_0_bit | DV_I_50_0_bit | DV_I_52_0_bit | DV_II_50_0_bit | DV_II_55_0_bit))
mask &= (((((W[46] ^ W[47]) >> 29) & 1) - 1) | ^(DV_I_43_0_bit | DV_I_50_0_bit | DV_II_47_0_bit | DV_II_48_0_bit | DV_II_52_0_bit | DV_II_53_0_bit))
mask &= (((((W[45] >> 4) ^ (W[48] >> 29)) & 1) - 1) | ^(DV_I_45_0_bit | DV_I_47_0_bit | DV_I_49_0_bit | DV_I_51_0_bit | DV_II_49_0_bit | DV_II_54_0_bit))
mask &= (((((W[45] ^ W[46]) >> 29) & 1) - 1) | ^(DV_I_49_0_bit | DV_I_52_0_bit | DV_II_46_0_bit | DV_II_47_0_bit | DV_II_51_0_bit | DV_II_52_0_bit))
mask &= (((((W[44] >> 4) ^ (W[47] >> 29)) & 1) - 1) | ^(DV_I_44_0_bit | DV_I_46_0_bit | DV_I_48_0_bit | DV_I_50_0_bit | DV_II_48_0_bit | DV_II_53_0_bit))
mask &= (((((W[43] >> 4) ^ (W[46] >> 29)) & 1) - 1) | ^(DV_I_43_0_bit | DV_I_45_0_bit | DV_I_47_0_bit | DV_I_49_0_bit | DV_II_47_0_bit | DV_II_52_0_bit))
mask &= (((((W[43] ^ W[44]) >> 29) & 1) - 1) | ^(DV_I_47_0_bit | DV_I_50_0_bit | DV_I_51_0_bit | DV_II_45_0_bit | DV_II_49_0_bit | DV_II_50_0_bit))
mask &= (((((W[42] >> 4) ^ (W[45] >> 29)) & 1) - 1) | ^(DV_I_44_0_bit | DV_I_46_0_bit | DV_I_48_0_bit | DV_I_52_0_bit | DV_II_46_0_bit | DV_II_51_0_bit))
mask &= (((((W[41] >> 4) ^ (W[44] >> 29)) & 1) - 1) | ^(DV_I_43_0_bit | DV_I_45_0_bit | DV_I_47_0_bit | DV_I_51_0_bit | DV_II_45_0_bit | DV_II_50_0_bit))
mask &= (((((W[40] ^ W[41]) >> 29) & 1) - 1) | ^(DV_I_44_0_bit | DV_I_47_0_bit | DV_I_48_0_bit | DV_II_46_0_bit | DV_II_47_0_bit | DV_II_56_0_bit))
mask &= (((((W[54] ^ W[55]) >> 29) & 1) - 1) | ^(DV_I_51_0_bit | DV_II_47_0_bit | DV_II_50_0_bit | DV_II_55_0_bit | DV_II_56_0_bit))
mask &= (((((W[53] ^ W[54]) >> 29) & 1) - 1) | ^(DV_I_50_0_bit | DV_II_46_0_bit | DV_II_49_0_bit | DV_II_54_0_bit | DV_II_55_0_bit))
mask &= (((((W[52] ^ W[53]) >> 29) & 1) - 1) | ^(DV_I_49_0_bit | DV_II_45_0_bit | DV_II_48_0_bit | DV_II_53_0_bit | DV_II_54_0_bit))
mask &= ((((W[50] ^ (W[53] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_I_50_0_bit | DV_I_52_0_bit | DV_II_46_0_bit | DV_II_48_0_bit | DV_II_54_0_bit))
mask &= (((((W[50] ^ W[51]) >> 29) & 1) - 1) | ^(DV_I_47_0_bit | DV_II_46_0_bit | DV_II_51_0_bit | DV_II_52_0_bit | DV_II_56_0_bit))
mask &= ((((W[49] ^ (W[52] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_I_49_0_bit | DV_I_51_0_bit | DV_II_45_0_bit | DV_II_47_0_bit | DV_II_53_0_bit))
mask &= ((((W[48] ^ (W[51] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_I_48_0_bit | DV_I_50_0_bit | DV_I_52_0_bit | DV_II_46_0_bit | DV_II_52_0_bit))
mask &= (((((W[42] ^ W[43]) >> 29) & 1) - 1) | ^(DV_I_46_0_bit | DV_I_49_0_bit | DV_I_50_0_bit | DV_II_48_0_bit | DV_II_49_0_bit))
mask &= (((((W[41] ^ W[42]) >> 29) & 1) - 1) | ^(DV_I_45_0_bit | DV_I_48_0_bit | DV_I_49_0_bit | DV_II_47_0_bit | DV_II_48_0_bit))
mask &= (((((W[40] >> 4) ^ (W[43] >> 29)) & 1) - 1) | ^(DV_I_44_0_bit | DV_I_46_0_bit | DV_I_50_0_bit | DV_II_49_0_bit | DV_II_56_0_bit))
mask &= (((((W[39] >> 4) ^ (W[42] >> 29)) & 1) - 1) | ^(DV_I_43_0_bit | DV_I_45_0_bit | DV_I_49_0_bit | DV_II_48_0_bit | DV_II_55_0_bit))
if (mask & (DV_I_44_0_bit | DV_I_48_0_bit | DV_II_47_0_bit | DV_II_54_0_bit | DV_II_56_0_bit)) != 0 {
mask &= (((((W[38] >> 4) ^ (W[41] >> 29)) & 1) - 1) | ^(DV_I_44_0_bit | DV_I_48_0_bit | DV_II_47_0_bit | DV_II_54_0_bit | DV_II_56_0_bit))
}
mask &= (((((W[37] >> 4) ^ (W[40] >> 29)) & 1) - 1) | ^(DV_I_43_0_bit | DV_I_47_0_bit | DV_II_46_0_bit | DV_II_53_0_bit | DV_II_55_0_bit))
if (mask & (DV_I_52_0_bit | DV_II_48_0_bit | DV_II_51_0_bit | DV_II_56_0_bit)) != 0 {
mask &= (((((W[55] ^ W[56]) >> 29) & 1) - 1) | ^(DV_I_52_0_bit | DV_II_48_0_bit | DV_II_51_0_bit | DV_II_56_0_bit))
}
if (mask & (DV_I_52_0_bit | DV_II_48_0_bit | DV_II_50_0_bit | DV_II_56_0_bit)) != 0 {
mask &= ((((W[52] ^ (W[55] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_I_52_0_bit | DV_II_48_0_bit | DV_II_50_0_bit | DV_II_56_0_bit))
}
if (mask & (DV_I_51_0_bit | DV_II_47_0_bit | DV_II_49_0_bit | DV_II_55_0_bit)) != 0 {
mask &= ((((W[51] ^ (W[54] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_I_51_0_bit | DV_II_47_0_bit | DV_II_49_0_bit | DV_II_55_0_bit))
}
if (mask & (DV_I_48_0_bit | DV_II_47_0_bit | DV_II_52_0_bit | DV_II_53_0_bit)) != 0 {
mask &= (((((W[51] ^ W[52]) >> 29) & 1) - 1) | ^(DV_I_48_0_bit | DV_II_47_0_bit | DV_II_52_0_bit | DV_II_53_0_bit))
}
if (mask & (DV_I_46_0_bit | DV_I_49_0_bit | DV_II_45_0_bit | DV_II_48_0_bit)) != 0 {
mask &= (((((W[36] >> 4) ^ (W[40] >> 29)) & 1) - 1) | ^(DV_I_46_0_bit | DV_I_49_0_bit | DV_II_45_0_bit | DV_II_48_0_bit))
}
if (mask & (DV_I_52_0_bit | DV_II_48_0_bit | DV_II_49_0_bit)) != 0 {
mask &= ((0 - (((W[53] ^ W[56]) >> 29) & 1)) | ^(DV_I_52_0_bit | DV_II_48_0_bit | DV_II_49_0_bit))
}
if (mask & (DV_I_50_0_bit | DV_II_46_0_bit | DV_II_47_0_bit)) != 0 {
mask &= ((0 - (((W[51] ^ W[54]) >> 29) & 1)) | ^(DV_I_50_0_bit | DV_II_46_0_bit | DV_II_47_0_bit))
}
if (mask & (DV_I_49_0_bit | DV_I_51_0_bit | DV_II_45_0_bit)) != 0 {
mask &= ((0 - (((W[50] ^ W[52]) >> 29) & 1)) | ^(DV_I_49_0_bit | DV_I_51_0_bit | DV_II_45_0_bit))
}
if (mask & (DV_I_48_0_bit | DV_I_50_0_bit | DV_I_52_0_bit)) != 0 {
mask &= ((0 - (((W[49] ^ W[51]) >> 29) & 1)) | ^(DV_I_48_0_bit | DV_I_50_0_bit | DV_I_52_0_bit))
}
if (mask & (DV_I_47_0_bit | DV_I_49_0_bit | DV_I_51_0_bit)) != 0 {
mask &= ((0 - (((W[48] ^ W[50]) >> 29) & 1)) | ^(DV_I_47_0_bit | DV_I_49_0_bit | DV_I_51_0_bit))
}
if (mask & (DV_I_46_0_bit | DV_I_48_0_bit | DV_I_50_0_bit)) != 0 {
mask &= ((0 - (((W[47] ^ W[49]) >> 29) & 1)) | ^(DV_I_46_0_bit | DV_I_48_0_bit | DV_I_50_0_bit))
}
if (mask & (DV_I_45_0_bit | DV_I_47_0_bit | DV_I_49_0_bit)) != 0 {
mask &= ((0 - (((W[46] ^ W[48]) >> 29) & 1)) | ^(DV_I_45_0_bit | DV_I_47_0_bit | DV_I_49_0_bit))
}
mask &= ((((W[45] ^ W[47]) & (1 << 6)) - (1 << 6)) | ^(DV_I_47_2_bit | DV_I_49_2_bit | DV_I_51_2_bit))
if (mask & (DV_I_44_0_bit | DV_I_46_0_bit | DV_I_48_0_bit)) != 0 {
mask &= ((0 - (((W[45] ^ W[47]) >> 29) & 1)) | ^(DV_I_44_0_bit | DV_I_46_0_bit | DV_I_48_0_bit))
}
mask &= (((((W[44] ^ W[46]) >> 6) & 1) - 1) | ^(DV_I_46_2_bit | DV_I_48_2_bit | DV_I_50_2_bit))
if (mask & (DV_I_43_0_bit | DV_I_45_0_bit | DV_I_47_0_bit)) != 0 {
mask &= ((0 - (((W[44] ^ W[46]) >> 29) & 1)) | ^(DV_I_43_0_bit | DV_I_45_0_bit | DV_I_47_0_bit))
}
mask &= ((0 - ((W[41] ^ (W[42] >> 5)) & (1 << 1))) | ^(DV_I_48_2_bit | DV_II_46_2_bit | DV_II_51_2_bit))
mask &= ((0 - ((W[40] ^ (W[41] >> 5)) & (1 << 1))) | ^(DV_I_47_2_bit | DV_I_51_2_bit | DV_II_50_2_bit))
if (mask & (DV_I_44_0_bit | DV_I_46_0_bit | DV_II_56_0_bit)) != 0 {
mask &= ((0 - (((W[40] ^ W[42]) >> 4) & 1)) | ^(DV_I_44_0_bit | DV_I_46_0_bit | DV_II_56_0_bit))
}
mask &= ((0 - ((W[39] ^ (W[40] >> 5)) & (1 << 1))) | ^(DV_I_46_2_bit | DV_I_50_2_bit | DV_II_49_2_bit))
if (mask & (DV_I_43_0_bit | DV_I_45_0_bit | DV_II_55_0_bit)) != 0 {
mask &= ((0 - (((W[39] ^ W[41]) >> 4) & 1)) | ^(DV_I_43_0_bit | DV_I_45_0_bit | DV_II_55_0_bit))
}
if (mask & (DV_I_44_0_bit | DV_II_54_0_bit | DV_II_56_0_bit)) != 0 {
mask &= ((0 - (((W[38] ^ W[40]) >> 4) & 1)) | ^(DV_I_44_0_bit | DV_II_54_0_bit | DV_II_56_0_bit))
}
if (mask & (DV_I_43_0_bit | DV_II_53_0_bit | DV_II_55_0_bit)) != 0 {
mask &= ((0 - (((W[37] ^ W[39]) >> 4) & 1)) | ^(DV_I_43_0_bit | DV_II_53_0_bit | DV_II_55_0_bit))
}
mask &= ((0 - ((W[36] ^ (W[37] >> 5)) & (1 << 1))) | ^(DV_I_47_2_bit | DV_I_50_2_bit | DV_II_46_2_bit))
if (mask & (DV_I_45_0_bit | DV_I_48_0_bit | DV_II_47_0_bit)) != 0 {
mask &= (((((W[35] >> 4) ^ (W[39] >> 29)) & 1) - 1) | ^(DV_I_45_0_bit | DV_I_48_0_bit | DV_II_47_0_bit))
}
if (mask & (DV_I_48_0_bit | DV_II_48_0_bit)) != 0 {
mask &= ((0 - ((W[63] ^ (W[64] >> 5)) & (1 << 0))) | ^(DV_I_48_0_bit | DV_II_48_0_bit))
}
if (mask & (DV_I_45_0_bit | DV_II_45_0_bit)) != 0 {
mask &= ((0 - ((W[63] ^ (W[64] >> 5)) & (1 << 1))) | ^(DV_I_45_0_bit | DV_II_45_0_bit))
}
if (mask & (DV_I_47_0_bit | DV_II_47_0_bit)) != 0 {
mask &= ((0 - ((W[62] ^ (W[63] >> 5)) & (1 << 0))) | ^(DV_I_47_0_bit | DV_II_47_0_bit))
}
if (mask & (DV_I_46_0_bit | DV_II_46_0_bit)) != 0 {
mask &= ((0 - ((W[61] ^ (W[62] >> 5)) & (1 << 0))) | ^(DV_I_46_0_bit | DV_II_46_0_bit))
}
mask &= ((0 - ((W[61] ^ (W[62] >> 5)) & (1 << 2))) | ^(DV_I_46_2_bit | DV_II_46_2_bit))
if (mask & (DV_I_45_0_bit | DV_II_45_0_bit)) != 0 {
mask &= ((0 - ((W[60] ^ (W[61] >> 5)) & (1 << 0))) | ^(DV_I_45_0_bit | DV_II_45_0_bit))
}
if (mask & (DV_II_51_0_bit | DV_II_54_0_bit)) != 0 {
mask &= (((((W[58] ^ W[59]) >> 29) & 1) - 1) | ^(DV_II_51_0_bit | DV_II_54_0_bit))
}
if (mask & (DV_II_50_0_bit | DV_II_53_0_bit)) != 0 {
mask &= (((((W[57] ^ W[58]) >> 29) & 1) - 1) | ^(DV_II_50_0_bit | DV_II_53_0_bit))
}
if (mask & (DV_II_52_0_bit | DV_II_54_0_bit)) != 0 {
mask &= ((((W[56] ^ (W[59] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_II_52_0_bit | DV_II_54_0_bit))
}
if (mask & (DV_II_51_0_bit | DV_II_52_0_bit)) != 0 {
mask &= ((0 - (((W[56] ^ W[59]) >> 29) & 1)) | ^(DV_II_51_0_bit | DV_II_52_0_bit))
}
if (mask & (DV_II_49_0_bit | DV_II_52_0_bit)) != 0 {
mask &= (((((W[56] ^ W[57]) >> 29) & 1) - 1) | ^(DV_II_49_0_bit | DV_II_52_0_bit))
}
if (mask & (DV_II_51_0_bit | DV_II_53_0_bit)) != 0 {
mask &= ((((W[55] ^ (W[58] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_II_51_0_bit | DV_II_53_0_bit))
}
if (mask & (DV_II_50_0_bit | DV_II_52_0_bit)) != 0 {
mask &= ((((W[54] ^ (W[57] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_II_50_0_bit | DV_II_52_0_bit))
}
if (mask & (DV_II_49_0_bit | DV_II_51_0_bit)) != 0 {
mask &= ((((W[53] ^ (W[56] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_II_49_0_bit | DV_II_51_0_bit))
}
mask &= ((((W[51] ^ (W[50] >> 5)) & (1 << 1)) - (1 << 1)) | ^(DV_I_50_2_bit | DV_II_46_2_bit))
mask &= ((((W[48] ^ W[50]) & (1 << 6)) - (1 << 6)) | ^(DV_I_50_2_bit | DV_II_46_2_bit))
if (mask & (DV_I_51_0_bit | DV_I_52_0_bit)) != 0 {
mask &= ((0 - (((W[48] ^ W[55]) >> 29) & 1)) | ^(DV_I_51_0_bit | DV_I_52_0_bit))
}
mask &= ((((W[47] ^ W[49]) & (1 << 6)) - (1 << 6)) | ^(DV_I_49_2_bit | DV_I_51_2_bit))
mask &= ((((W[48] ^ (W[47] >> 5)) & (1 << 1)) - (1 << 1)) | ^(DV_I_47_2_bit | DV_II_51_2_bit))
mask &= ((((W[46] ^ W[48]) & (1 << 6)) - (1 << 6)) | ^(DV_I_48_2_bit | DV_I_50_2_bit))
mask &= ((((W[47] ^ (W[46] >> 5)) & (1 << 1)) - (1 << 1)) | ^(DV_I_46_2_bit | DV_II_50_2_bit))
mask &= ((0 - ((W[44] ^ (W[45] >> 5)) & (1 << 1))) | ^(DV_I_51_2_bit | DV_II_49_2_bit))
mask &= ((((W[43] ^ W[45]) & (1 << 6)) - (1 << 6)) | ^(DV_I_47_2_bit | DV_I_49_2_bit))
mask &= (((((W[42] ^ W[44]) >> 6) & 1) - 1) | ^(DV_I_46_2_bit | DV_I_48_2_bit))
mask &= ((((W[43] ^ (W[42] >> 5)) & (1 << 1)) - (1 << 1)) | ^(DV_II_46_2_bit | DV_II_51_2_bit))
mask &= ((((W[42] ^ (W[41] >> 5)) & (1 << 1)) - (1 << 1)) | ^(DV_I_51_2_bit | DV_II_50_2_bit))
mask &= ((((W[41] ^ (W[40] >> 5)) & (1 << 1)) - (1 << 1)) | ^(DV_I_50_2_bit | DV_II_49_2_bit))
if (mask & (DV_I_52_0_bit | DV_II_51_0_bit)) != 0 {
mask &= ((((W[39] ^ (W[43] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_I_52_0_bit | DV_II_51_0_bit))
}
if (mask & (DV_I_51_0_bit | DV_II_50_0_bit)) != 0 {
mask &= ((((W[38] ^ (W[42] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_I_51_0_bit | DV_II_50_0_bit))
}
if (mask & (DV_I_48_2_bit | DV_I_51_2_bit)) != 0 {
mask &= ((0 - ((W[37] ^ (W[38] >> 5)) & (1 << 1))) | ^(DV_I_48_2_bit | DV_I_51_2_bit))
}
if (mask & (DV_I_50_0_bit | DV_II_49_0_bit)) != 0 {
mask &= ((((W[37] ^ (W[41] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_I_50_0_bit | DV_II_49_0_bit))
}
if (mask & (DV_II_52_0_bit | DV_II_54_0_bit)) != 0 {
mask &= ((0 - ((W[36] ^ W[38]) & (1 << 4))) | ^(DV_II_52_0_bit | DV_II_54_0_bit))
}
mask &= ((0 - ((W[35] ^ (W[36] >> 5)) & (1 << 1))) | ^(DV_I_46_2_bit | DV_I_49_2_bit))
if (mask & (DV_I_51_0_bit | DV_II_47_0_bit)) != 0 {
mask &= ((((W[35] ^ (W[39] >> 25)) & (1 << 3)) - (1 << 3)) | ^(DV_I_51_0_bit | DV_II_47_0_bit))
}
if mask != 0 {
if (mask & DV_I_43_0_bit) != 0 {
if not((W[61]^(W[62]>>5))&(1<<1)) != 0 ||
not(not((W[59]^(W[63]>>25))&(1<<5))) != 0 ||
not((W[58]^(W[63]>>30))&(1<<0)) != 0 {
mask &= ^DV_I_43_0_bit
}
}
if (mask & DV_I_44_0_bit) != 0 {
if not((W[62]^(W[63]>>5))&(1<<1)) != 0 ||
not(not((W[60]^(W[64]>>25))&(1<<5))) != 0 ||
not((W[59]^(W[64]>>30))&(1<<0)) != 0 {
mask &= ^DV_I_44_0_bit
}
}
if (mask & DV_I_46_2_bit) != 0 {
mask &= ((^((W[40] ^ W[42]) >> 2)) | ^DV_I_46_2_bit)
}
if (mask & DV_I_47_2_bit) != 0 {
if not((W[62]^(W[63]>>5))&(1<<2)) != 0 ||
not(not((W[41]^W[43])&(1<<6))) != 0 {
mask &= ^DV_I_47_2_bit
}
}
if (mask & DV_I_48_2_bit) != 0 {
if not((W[63]^(W[64]>>5))&(1<<2)) != 0 ||
not(not((W[48]^(W[49]<<5))&(1<<6))) != 0 {
mask &= ^DV_I_48_2_bit
}
}
if (mask & DV_I_49_2_bit) != 0 {
if not(not((W[49]^(W[50]<<5))&(1<<6))) != 0 ||
not((W[42]^W[50])&(1<<1)) != 0 ||
not(not((W[39]^(W[40]<<5))&(1<<6))) != 0 ||
not((W[38]^W[40])&(1<<1)) != 0 {
mask &= ^DV_I_49_2_bit
}
}
if (mask & DV_I_50_0_bit) != 0 {
mask &= (((W[36] ^ W[37]) << 7) | ^DV_I_50_0_bit)
}
if (mask & DV_I_50_2_bit) != 0 {
mask &= (((W[43] ^ W[51]) << 11) | ^DV_I_50_2_bit)
}
if (mask & DV_I_51_0_bit) != 0 {
mask &= (((W[37] ^ W[38]) << 9) | ^DV_I_51_0_bit)
}
if (mask & DV_I_51_2_bit) != 0 {
if not(not((W[51]^(W[52]<<5))&(1<<6))) != 0 ||
not(not((W[49]^W[51])&(1<<6))) != 0 ||
not(not((W[37]^(W[37]>>5))&(1<<1))) != 0 ||
not(not((W[35]^(W[39]>>25))&(1<<5))) != 0 {
mask &= ^DV_I_51_2_bit
}
}
if (mask & DV_I_52_0_bit) != 0 {
mask &= (((W[38] ^ W[39]) << 11) | ^DV_I_52_0_bit)
}
if (mask & DV_II_46_2_bit) != 0 {
mask &= (((W[47] ^ W[51]) << 17) | ^DV_II_46_2_bit)
}
if (mask & DV_II_48_0_bit) != 0 {
if not(not((W[36]^(W[40]>>25))&(1<<3))) != 0 ||
not((W[35]^(W[40]<<2))&(1<<30)) != 0 {
mask &= ^DV_II_48_0_bit
}
}
if (mask & DV_II_49_0_bit) != 0 {
if not(not((W[37]^(W[41]>>25))&(1<<3))) != 0 ||
not((W[36]^(W[41]<<2))&(1<<30)) != 0 {
mask &= ^DV_II_49_0_bit
}
}
if (mask & DV_II_49_2_bit) != 0 {
if not(not((W[53]^(W[54]<<5))&(1<<6))) != 0 ||
not(not((W[51]^W[53])&(1<<6))) != 0 ||
not((W[50]^W[54])&(1<<1)) != 0 ||
not(not((W[45]^(W[46]<<5))&(1<<6))) != 0 ||
not(not((W[37]^(W[41]>>25))&(1<<5))) != 0 ||
not((W[36]^(W[41]>>30))&(1<<0)) != 0 {
mask &= ^DV_II_49_2_bit
}
}
if (mask & DV_II_50_0_bit) != 0 {
if not((W[55]^W[58])&(1<<29)) != 0 ||
not(not((W[38]^(W[42]>>25))&(1<<3))) != 0 ||
not((W[37]^(W[42]<<2))&(1<<30)) != 0 {
mask &= ^DV_II_50_0_bit
}
}
if (mask & DV_II_50_2_bit) != 0 {
if not(not((W[54]^(W[55]<<5))&(1<<6))) != 0 ||
not(not((W[52]^W[54])&(1<<6))) != 0 ||
not((W[51]^W[55])&(1<<1)) != 0 ||
not((W[45]^W[47])&(1<<1)) != 0 ||
not(not((W[38]^(W[42]>>25))&(1<<5))) != 0 ||
not((W[37]^(W[42]>>30))&(1<<0)) != 0 {
mask &= ^DV_II_50_2_bit
}
}
if (mask & DV_II_51_0_bit) != 0 {
if not(not((W[39]^(W[43]>>25))&(1<<3))) != 0 ||
not((W[38]^(W[43]<<2))&(1<<30)) != 0 {
mask &= ^DV_II_51_0_bit
}
}
if (mask & DV_II_51_2_bit) != 0 {
if not(not((W[55]^(W[56]<<5))&(1<<6))) != 0 ||
not(not((W[53]^W[55])&(1<<6))) != 0 ||
not((W[52]^W[56])&(1<<1)) != 0 ||
not((W[46]^W[48])&(1<<1)) != 0 ||
not(not((W[39]^(W[43]>>25))&(1<<5))) != 0 ||
not((W[38]^(W[43]>>30))&(1<<0)) != 0 {
mask &= ^DV_II_51_2_bit
}
}
if (mask & DV_II_52_0_bit) != 0 {
if not(not((W[59]^W[60])&(1<<29))) != 0 ||
not(not((W[40]^(W[44]>>25))&(1<<3))) != 0 ||
not(not((W[40]^(W[44]>>25))&(1<<4))) != 0 ||
not((W[39]^(W[44]<<2))&(1<<30)) != 0 {
mask &= ^DV_II_52_0_bit
}
}
if (mask & DV_II_53_0_bit) != 0 {
if not((W[58]^W[61])&(1<<29)) != 0 ||
not(not((W[57]^(W[61]>>25))&(1<<4))) != 0 ||
not(not((W[41]^(W[45]>>25))&(1<<3))) != 0 ||
not(not((W[41]^(W[45]>>25))&(1<<4))) != 0 {
mask &= ^DV_II_53_0_bit
}
}
if (mask & DV_II_54_0_bit) != 0 {
if not(not((W[58]^(W[62]>>25))&(1<<4))) != 0 ||
not(not((W[42]^(W[46]>>25))&(1<<3))) != 0 ||
not(not((W[42]^(W[46]>>25))&(1<<4))) != 0 {
mask &= ^DV_II_54_0_bit
}
}
if (mask & DV_II_55_0_bit) != 0 {
if not(not((W[59]^(W[63]>>25))&(1<<4))) != 0 ||
not(not((W[57]^(W[59]>>25))&(1<<4))) != 0 ||
not(not((W[43]^(W[47]>>25))&(1<<3))) != 0 ||
not(not((W[43]^(W[47]>>25))&(1<<4))) != 0 {
mask &= ^DV_II_55_0_bit
}
}
if (mask & DV_II_56_0_bit) != 0 {
if not(not((W[60]^(W[64]>>25))&(1<<4))) != 0 ||
not(not((W[44]^(W[48]>>25))&(1<<3))) != 0 ||
not(not((W[44]^(W[48]>>25))&(1<<4))) != 0 {
mask &= ^DV_II_56_0_bit
}
}
}
return mask
}
func not(x uint32) uint32 {
if x == 0 {
return 1
}
return 0
}
//go:nosplit
func SHA1_dvs() []DvInfo {
return sha1_dvs
}

View File

@ -1,14 +0,0 @@
//go:build !noasm && gc && amd64 && !arm64
// +build !noasm,gc,amd64,!arm64
package ubc
func CalculateDvMaskAMD64(W [80]uint32) uint32
// Check takes as input an expanded message block and verifies the unavoidable bitconditions
// for all listed DVs. It returns a dvmask where each bit belonging to a DV is set if all
// unavoidable bitconditions for that DV have been met.
// Thus, one needs to do the recompression check for each DV that has its bit set.
func CalculateDvMask(W [80]uint32) uint32 {
return CalculateDvMaskAMD64(W)
}

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +0,0 @@
//go:build !noasm && gc && arm64 && !amd64
// +build !noasm,gc,arm64,!amd64
package ubc
func CalculateDvMaskARM64(W [80]uint32) uint32
// Check takes as input an expanded message block and verifies the unavoidable
// bitconditions for all listed DVs. It returns a dvmask where each bit belonging
// to a DV is set if all unavoidable bitconditions for that DV have been met.
func CalculateDvMask(W [80]uint32) uint32 {
return CalculateDvMaskARM64(W)
}

File diff suppressed because it is too large Load Diff

View File

@ -1,368 +0,0 @@
// Based on the C implementation from Marc Stevens and Dan Shumow.
// https://github.com/cr-marcstevens/sha1collisiondetection
package ubc
type DvInfo struct {
// DvType, DvK and DvB define the DV: I(K,B) or II(K,B) (see the paper).
// https://marc-stevens.nl/research/papers/C13-S.pdf
DvType uint32
DvK uint32
DvB uint32
// TestT is the step to do the recompression from for collision detection.
TestT uint32
// MaskI and MaskB define the bit to check for each DV in the dvmask returned by ubc_check.
MaskI uint32
MaskB uint32
// Dm is the expanded message block XOR-difference defined by the DV.
Dm [80]uint32
}
// CalculateDvMask takes as input an expanded message block and verifies the unavoidable bitconditions
// for all listed DVs. It returns a dvmask where each bit belonging to a DV is set if all
// unavoidable bitconditions for that DV have been met.
// Thus, one needs to do the recompression check for each DV that has its bit set.
func CalculateDvMaskGeneric(W [80]uint32) uint32 {
mask := uint32(0xFFFFFFFF)
mask &= (((((W[44] ^ W[45]) >> 29) & 1) - 1) | ^(DV_I_48_0_bit | DV_I_51_0_bit | DV_I_52_0_bit | DV_II_45_0_bit | DV_II_46_0_bit | DV_II_50_0_bit | DV_II_51_0_bit))
mask &= (((((W[49] ^ W[50]) >> 29) & 1) - 1) | ^(DV_I_46_0_bit | DV_II_45_0_bit | DV_II_50_0_bit | DV_II_51_0_bit | DV_II_55_0_bit | DV_II_56_0_bit))
mask &= (((((W[48] ^ W[49]) >> 29) & 1) - 1) | ^(DV_I_45_0_bit | DV_I_52_0_bit | DV_II_49_0_bit | DV_II_50_0_bit | DV_II_54_0_bit | DV_II_55_0_bit))
mask &= ((((W[47] ^ (W[50] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_I_47_0_bit | DV_I_49_0_bit | DV_I_51_0_bit | DV_II_45_0_bit | DV_II_51_0_bit | DV_II_56_0_bit))
mask &= (((((W[47] ^ W[48]) >> 29) & 1) - 1) | ^(DV_I_44_0_bit | DV_I_51_0_bit | DV_II_48_0_bit | DV_II_49_0_bit | DV_II_53_0_bit | DV_II_54_0_bit))
mask &= (((((W[46] >> 4) ^ (W[49] >> 29)) & 1) - 1) | ^(DV_I_46_0_bit | DV_I_48_0_bit | DV_I_50_0_bit | DV_I_52_0_bit | DV_II_50_0_bit | DV_II_55_0_bit))
mask &= (((((W[46] ^ W[47]) >> 29) & 1) - 1) | ^(DV_I_43_0_bit | DV_I_50_0_bit | DV_II_47_0_bit | DV_II_48_0_bit | DV_II_52_0_bit | DV_II_53_0_bit))
mask &= (((((W[45] >> 4) ^ (W[48] >> 29)) & 1) - 1) | ^(DV_I_45_0_bit | DV_I_47_0_bit | DV_I_49_0_bit | DV_I_51_0_bit | DV_II_49_0_bit | DV_II_54_0_bit))
mask &= (((((W[45] ^ W[46]) >> 29) & 1) - 1) | ^(DV_I_49_0_bit | DV_I_52_0_bit | DV_II_46_0_bit | DV_II_47_0_bit | DV_II_51_0_bit | DV_II_52_0_bit))
mask &= (((((W[44] >> 4) ^ (W[47] >> 29)) & 1) - 1) | ^(DV_I_44_0_bit | DV_I_46_0_bit | DV_I_48_0_bit | DV_I_50_0_bit | DV_II_48_0_bit | DV_II_53_0_bit))
mask &= (((((W[43] >> 4) ^ (W[46] >> 29)) & 1) - 1) | ^(DV_I_43_0_bit | DV_I_45_0_bit | DV_I_47_0_bit | DV_I_49_0_bit | DV_II_47_0_bit | DV_II_52_0_bit))
mask &= (((((W[43] ^ W[44]) >> 29) & 1) - 1) | ^(DV_I_47_0_bit | DV_I_50_0_bit | DV_I_51_0_bit | DV_II_45_0_bit | DV_II_49_0_bit | DV_II_50_0_bit))
mask &= (((((W[42] >> 4) ^ (W[45] >> 29)) & 1) - 1) | ^(DV_I_44_0_bit | DV_I_46_0_bit | DV_I_48_0_bit | DV_I_52_0_bit | DV_II_46_0_bit | DV_II_51_0_bit))
mask &= (((((W[41] >> 4) ^ (W[44] >> 29)) & 1) - 1) | ^(DV_I_43_0_bit | DV_I_45_0_bit | DV_I_47_0_bit | DV_I_51_0_bit | DV_II_45_0_bit | DV_II_50_0_bit))
mask &= (((((W[40] ^ W[41]) >> 29) & 1) - 1) | ^(DV_I_44_0_bit | DV_I_47_0_bit | DV_I_48_0_bit | DV_II_46_0_bit | DV_II_47_0_bit | DV_II_56_0_bit))
mask &= (((((W[54] ^ W[55]) >> 29) & 1) - 1) | ^(DV_I_51_0_bit | DV_II_47_0_bit | DV_II_50_0_bit | DV_II_55_0_bit | DV_II_56_0_bit))
mask &= (((((W[53] ^ W[54]) >> 29) & 1) - 1) | ^(DV_I_50_0_bit | DV_II_46_0_bit | DV_II_49_0_bit | DV_II_54_0_bit | DV_II_55_0_bit))
mask &= (((((W[52] ^ W[53]) >> 29) & 1) - 1) | ^(DV_I_49_0_bit | DV_II_45_0_bit | DV_II_48_0_bit | DV_II_53_0_bit | DV_II_54_0_bit))
mask &= ((((W[50] ^ (W[53] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_I_50_0_bit | DV_I_52_0_bit | DV_II_46_0_bit | DV_II_48_0_bit | DV_II_54_0_bit))
mask &= (((((W[50] ^ W[51]) >> 29) & 1) - 1) | ^(DV_I_47_0_bit | DV_II_46_0_bit | DV_II_51_0_bit | DV_II_52_0_bit | DV_II_56_0_bit))
mask &= ((((W[49] ^ (W[52] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_I_49_0_bit | DV_I_51_0_bit | DV_II_45_0_bit | DV_II_47_0_bit | DV_II_53_0_bit))
mask &= ((((W[48] ^ (W[51] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_I_48_0_bit | DV_I_50_0_bit | DV_I_52_0_bit | DV_II_46_0_bit | DV_II_52_0_bit))
mask &= (((((W[42] ^ W[43]) >> 29) & 1) - 1) | ^(DV_I_46_0_bit | DV_I_49_0_bit | DV_I_50_0_bit | DV_II_48_0_bit | DV_II_49_0_bit))
mask &= (((((W[41] ^ W[42]) >> 29) & 1) - 1) | ^(DV_I_45_0_bit | DV_I_48_0_bit | DV_I_49_0_bit | DV_II_47_0_bit | DV_II_48_0_bit))
mask &= (((((W[40] >> 4) ^ (W[43] >> 29)) & 1) - 1) | ^(DV_I_44_0_bit | DV_I_46_0_bit | DV_I_50_0_bit | DV_II_49_0_bit | DV_II_56_0_bit))
mask &= (((((W[39] >> 4) ^ (W[42] >> 29)) & 1) - 1) | ^(DV_I_43_0_bit | DV_I_45_0_bit | DV_I_49_0_bit | DV_II_48_0_bit | DV_II_55_0_bit))
if (mask & (DV_I_44_0_bit | DV_I_48_0_bit | DV_II_47_0_bit | DV_II_54_0_bit | DV_II_56_0_bit)) != 0 {
mask &= (((((W[38] >> 4) ^ (W[41] >> 29)) & 1) - 1) | ^(DV_I_44_0_bit | DV_I_48_0_bit | DV_II_47_0_bit | DV_II_54_0_bit | DV_II_56_0_bit))
}
mask &= (((((W[37] >> 4) ^ (W[40] >> 29)) & 1) - 1) | ^(DV_I_43_0_bit | DV_I_47_0_bit | DV_II_46_0_bit | DV_II_53_0_bit | DV_II_55_0_bit))
if (mask & (DV_I_52_0_bit | DV_II_48_0_bit | DV_II_51_0_bit | DV_II_56_0_bit)) != 0 {
mask &= (((((W[55] ^ W[56]) >> 29) & 1) - 1) | ^(DV_I_52_0_bit | DV_II_48_0_bit | DV_II_51_0_bit | DV_II_56_0_bit))
}
if (mask & (DV_I_52_0_bit | DV_II_48_0_bit | DV_II_50_0_bit | DV_II_56_0_bit)) != 0 {
mask &= ((((W[52] ^ (W[55] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_I_52_0_bit | DV_II_48_0_bit | DV_II_50_0_bit | DV_II_56_0_bit))
}
if (mask & (DV_I_51_0_bit | DV_II_47_0_bit | DV_II_49_0_bit | DV_II_55_0_bit)) != 0 {
mask &= ((((W[51] ^ (W[54] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_I_51_0_bit | DV_II_47_0_bit | DV_II_49_0_bit | DV_II_55_0_bit))
}
if (mask & (DV_I_48_0_bit | DV_II_47_0_bit | DV_II_52_0_bit | DV_II_53_0_bit)) != 0 {
mask &= (((((W[51] ^ W[52]) >> 29) & 1) - 1) | ^(DV_I_48_0_bit | DV_II_47_0_bit | DV_II_52_0_bit | DV_II_53_0_bit))
}
if (mask & (DV_I_46_0_bit | DV_I_49_0_bit | DV_II_45_0_bit | DV_II_48_0_bit)) != 0 {
mask &= (((((W[36] >> 4) ^ (W[40] >> 29)) & 1) - 1) | ^(DV_I_46_0_bit | DV_I_49_0_bit | DV_II_45_0_bit | DV_II_48_0_bit))
}
if (mask & (DV_I_52_0_bit | DV_II_48_0_bit | DV_II_49_0_bit)) != 0 {
mask &= ((0 - (((W[53] ^ W[56]) >> 29) & 1)) | ^(DV_I_52_0_bit | DV_II_48_0_bit | DV_II_49_0_bit))
}
if (mask & (DV_I_50_0_bit | DV_II_46_0_bit | DV_II_47_0_bit)) != 0 {
mask &= ((0 - (((W[51] ^ W[54]) >> 29) & 1)) | ^(DV_I_50_0_bit | DV_II_46_0_bit | DV_II_47_0_bit))
}
if (mask & (DV_I_49_0_bit | DV_I_51_0_bit | DV_II_45_0_bit)) != 0 {
mask &= ((0 - (((W[50] ^ W[52]) >> 29) & 1)) | ^(DV_I_49_0_bit | DV_I_51_0_bit | DV_II_45_0_bit))
}
if (mask & (DV_I_48_0_bit | DV_I_50_0_bit | DV_I_52_0_bit)) != 0 {
mask &= ((0 - (((W[49] ^ W[51]) >> 29) & 1)) | ^(DV_I_48_0_bit | DV_I_50_0_bit | DV_I_52_0_bit))
}
if (mask & (DV_I_47_0_bit | DV_I_49_0_bit | DV_I_51_0_bit)) != 0 {
mask &= ((0 - (((W[48] ^ W[50]) >> 29) & 1)) | ^(DV_I_47_0_bit | DV_I_49_0_bit | DV_I_51_0_bit))
}
if (mask & (DV_I_46_0_bit | DV_I_48_0_bit | DV_I_50_0_bit)) != 0 {
mask &= ((0 - (((W[47] ^ W[49]) >> 29) & 1)) | ^(DV_I_46_0_bit | DV_I_48_0_bit | DV_I_50_0_bit))
}
if (mask & (DV_I_45_0_bit | DV_I_47_0_bit | DV_I_49_0_bit)) != 0 {
mask &= ((0 - (((W[46] ^ W[48]) >> 29) & 1)) | ^(DV_I_45_0_bit | DV_I_47_0_bit | DV_I_49_0_bit))
}
mask &= ((((W[45] ^ W[47]) & (1 << 6)) - (1 << 6)) | ^(DV_I_47_2_bit | DV_I_49_2_bit | DV_I_51_2_bit))
if (mask & (DV_I_44_0_bit | DV_I_46_0_bit | DV_I_48_0_bit)) != 0 {
mask &= ((0 - (((W[45] ^ W[47]) >> 29) & 1)) | ^(DV_I_44_0_bit | DV_I_46_0_bit | DV_I_48_0_bit))
}
mask &= (((((W[44] ^ W[46]) >> 6) & 1) - 1) | ^(DV_I_46_2_bit | DV_I_48_2_bit | DV_I_50_2_bit))
if (mask & (DV_I_43_0_bit | DV_I_45_0_bit | DV_I_47_0_bit)) != 0 {
mask &= ((0 - (((W[44] ^ W[46]) >> 29) & 1)) | ^(DV_I_43_0_bit | DV_I_45_0_bit | DV_I_47_0_bit))
}
mask &= ((0 - ((W[41] ^ (W[42] >> 5)) & (1 << 1))) | ^(DV_I_48_2_bit | DV_II_46_2_bit | DV_II_51_2_bit))
mask &= ((0 - ((W[40] ^ (W[41] >> 5)) & (1 << 1))) | ^(DV_I_47_2_bit | DV_I_51_2_bit | DV_II_50_2_bit))
if (mask & (DV_I_44_0_bit | DV_I_46_0_bit | DV_II_56_0_bit)) != 0 {
mask &= ((0 - (((W[40] ^ W[42]) >> 4) & 1)) | ^(DV_I_44_0_bit | DV_I_46_0_bit | DV_II_56_0_bit))
}
mask &= ((0 - ((W[39] ^ (W[40] >> 5)) & (1 << 1))) | ^(DV_I_46_2_bit | DV_I_50_2_bit | DV_II_49_2_bit))
if (mask & (DV_I_43_0_bit | DV_I_45_0_bit | DV_II_55_0_bit)) != 0 {
mask &= ((0 - (((W[39] ^ W[41]) >> 4) & 1)) | ^(DV_I_43_0_bit | DV_I_45_0_bit | DV_II_55_0_bit))
}
if (mask & (DV_I_44_0_bit | DV_II_54_0_bit | DV_II_56_0_bit)) != 0 {
mask &= ((0 - (((W[38] ^ W[40]) >> 4) & 1)) | ^(DV_I_44_0_bit | DV_II_54_0_bit | DV_II_56_0_bit))
}
if (mask & (DV_I_43_0_bit | DV_II_53_0_bit | DV_II_55_0_bit)) != 0 {
mask &= ((0 - (((W[37] ^ W[39]) >> 4) & 1)) | ^(DV_I_43_0_bit | DV_II_53_0_bit | DV_II_55_0_bit))
}
mask &= ((0 - ((W[36] ^ (W[37] >> 5)) & (1 << 1))) | ^(DV_I_47_2_bit | DV_I_50_2_bit | DV_II_46_2_bit))
if (mask & (DV_I_45_0_bit | DV_I_48_0_bit | DV_II_47_0_bit)) != 0 {
mask &= (((((W[35] >> 4) ^ (W[39] >> 29)) & 1) - 1) | ^(DV_I_45_0_bit | DV_I_48_0_bit | DV_II_47_0_bit))
}
if (mask & (DV_I_48_0_bit | DV_II_48_0_bit)) != 0 {
mask &= ((0 - ((W[63] ^ (W[64] >> 5)) & (1 << 0))) | ^(DV_I_48_0_bit | DV_II_48_0_bit))
}
if (mask & (DV_I_45_0_bit | DV_II_45_0_bit)) != 0 {
mask &= ((0 - ((W[63] ^ (W[64] >> 5)) & (1 << 1))) | ^(DV_I_45_0_bit | DV_II_45_0_bit))
}
if (mask & (DV_I_47_0_bit | DV_II_47_0_bit)) != 0 {
mask &= ((0 - ((W[62] ^ (W[63] >> 5)) & (1 << 0))) | ^(DV_I_47_0_bit | DV_II_47_0_bit))
}
if (mask & (DV_I_46_0_bit | DV_II_46_0_bit)) != 0 {
mask &= ((0 - ((W[61] ^ (W[62] >> 5)) & (1 << 0))) | ^(DV_I_46_0_bit | DV_II_46_0_bit))
}
mask &= ((0 - ((W[61] ^ (W[62] >> 5)) & (1 << 2))) | ^(DV_I_46_2_bit | DV_II_46_2_bit))
if (mask & (DV_I_45_0_bit | DV_II_45_0_bit)) != 0 {
mask &= ((0 - ((W[60] ^ (W[61] >> 5)) & (1 << 0))) | ^(DV_I_45_0_bit | DV_II_45_0_bit))
}
if (mask & (DV_II_51_0_bit | DV_II_54_0_bit)) != 0 {
mask &= (((((W[58] ^ W[59]) >> 29) & 1) - 1) | ^(DV_II_51_0_bit | DV_II_54_0_bit))
}
if (mask & (DV_II_50_0_bit | DV_II_53_0_bit)) != 0 {
mask &= (((((W[57] ^ W[58]) >> 29) & 1) - 1) | ^(DV_II_50_0_bit | DV_II_53_0_bit))
}
if (mask & (DV_II_52_0_bit | DV_II_54_0_bit)) != 0 {
mask &= ((((W[56] ^ (W[59] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_II_52_0_bit | DV_II_54_0_bit))
}
if (mask & (DV_II_51_0_bit | DV_II_52_0_bit)) != 0 {
mask &= ((0 - (((W[56] ^ W[59]) >> 29) & 1)) | ^(DV_II_51_0_bit | DV_II_52_0_bit))
}
if (mask & (DV_II_49_0_bit | DV_II_52_0_bit)) != 0 {
mask &= (((((W[56] ^ W[57]) >> 29) & 1) - 1) | ^(DV_II_49_0_bit | DV_II_52_0_bit))
}
if (mask & (DV_II_51_0_bit | DV_II_53_0_bit)) != 0 {
mask &= ((((W[55] ^ (W[58] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_II_51_0_bit | DV_II_53_0_bit))
}
if (mask & (DV_II_50_0_bit | DV_II_52_0_bit)) != 0 {
mask &= ((((W[54] ^ (W[57] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_II_50_0_bit | DV_II_52_0_bit))
}
if (mask & (DV_II_49_0_bit | DV_II_51_0_bit)) != 0 {
mask &= ((((W[53] ^ (W[56] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_II_49_0_bit | DV_II_51_0_bit))
}
mask &= ((((W[51] ^ (W[50] >> 5)) & (1 << 1)) - (1 << 1)) | ^(DV_I_50_2_bit | DV_II_46_2_bit))
mask &= ((((W[48] ^ W[50]) & (1 << 6)) - (1 << 6)) | ^(DV_I_50_2_bit | DV_II_46_2_bit))
if (mask & (DV_I_51_0_bit | DV_I_52_0_bit)) != 0 {
mask &= ((0 - (((W[48] ^ W[55]) >> 29) & 1)) | ^(DV_I_51_0_bit | DV_I_52_0_bit))
}
mask &= ((((W[47] ^ W[49]) & (1 << 6)) - (1 << 6)) | ^(DV_I_49_2_bit | DV_I_51_2_bit))
mask &= ((((W[48] ^ (W[47] >> 5)) & (1 << 1)) - (1 << 1)) | ^(DV_I_47_2_bit | DV_II_51_2_bit))
mask &= ((((W[46] ^ W[48]) & (1 << 6)) - (1 << 6)) | ^(DV_I_48_2_bit | DV_I_50_2_bit))
mask &= ((((W[47] ^ (W[46] >> 5)) & (1 << 1)) - (1 << 1)) | ^(DV_I_46_2_bit | DV_II_50_2_bit))
mask &= ((0 - ((W[44] ^ (W[45] >> 5)) & (1 << 1))) | ^(DV_I_51_2_bit | DV_II_49_2_bit))
mask &= ((((W[43] ^ W[45]) & (1 << 6)) - (1 << 6)) | ^(DV_I_47_2_bit | DV_I_49_2_bit))
mask &= (((((W[42] ^ W[44]) >> 6) & 1) - 1) | ^(DV_I_46_2_bit | DV_I_48_2_bit))
mask &= ((((W[43] ^ (W[42] >> 5)) & (1 << 1)) - (1 << 1)) | ^(DV_II_46_2_bit | DV_II_51_2_bit))
mask &= ((((W[42] ^ (W[41] >> 5)) & (1 << 1)) - (1 << 1)) | ^(DV_I_51_2_bit | DV_II_50_2_bit))
mask &= ((((W[41] ^ (W[40] >> 5)) & (1 << 1)) - (1 << 1)) | ^(DV_I_50_2_bit | DV_II_49_2_bit))
if (mask & (DV_I_52_0_bit | DV_II_51_0_bit)) != 0 {
mask &= ((((W[39] ^ (W[43] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_I_52_0_bit | DV_II_51_0_bit))
}
if (mask & (DV_I_51_0_bit | DV_II_50_0_bit)) != 0 {
mask &= ((((W[38] ^ (W[42] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_I_51_0_bit | DV_II_50_0_bit))
}
if (mask & (DV_I_48_2_bit | DV_I_51_2_bit)) != 0 {
mask &= ((0 - ((W[37] ^ (W[38] >> 5)) & (1 << 1))) | ^(DV_I_48_2_bit | DV_I_51_2_bit))
}
if (mask & (DV_I_50_0_bit | DV_II_49_0_bit)) != 0 {
mask &= ((((W[37] ^ (W[41] >> 25)) & (1 << 4)) - (1 << 4)) | ^(DV_I_50_0_bit | DV_II_49_0_bit))
}
if (mask & (DV_II_52_0_bit | DV_II_54_0_bit)) != 0 {
mask &= ((0 - ((W[36] ^ W[38]) & (1 << 4))) | ^(DV_II_52_0_bit | DV_II_54_0_bit))
}
mask &= ((0 - ((W[35] ^ (W[36] >> 5)) & (1 << 1))) | ^(DV_I_46_2_bit | DV_I_49_2_bit))
if (mask & (DV_I_51_0_bit | DV_II_47_0_bit)) != 0 {
mask &= ((((W[35] ^ (W[39] >> 25)) & (1 << 3)) - (1 << 3)) | ^(DV_I_51_0_bit | DV_II_47_0_bit))
}
if mask != 0 {
if (mask & DV_I_43_0_bit) != 0 {
if not((W[61]^(W[62]>>5))&(1<<1)) != 0 ||
not(not((W[59]^(W[63]>>25))&(1<<5))) != 0 ||
not((W[58]^(W[63]>>30))&(1<<0)) != 0 {
mask &= ^DV_I_43_0_bit
}
}
if (mask & DV_I_44_0_bit) != 0 {
if not((W[62]^(W[63]>>5))&(1<<1)) != 0 ||
not(not((W[60]^(W[64]>>25))&(1<<5))) != 0 ||
not((W[59]^(W[64]>>30))&(1<<0)) != 0 {
mask &= ^DV_I_44_0_bit
}
}
if (mask & DV_I_46_2_bit) != 0 {
mask &= ((^((W[40] ^ W[42]) >> 2)) | ^DV_I_46_2_bit)
}
if (mask & DV_I_47_2_bit) != 0 {
if not((W[62]^(W[63]>>5))&(1<<2)) != 0 ||
not(not((W[41]^W[43])&(1<<6))) != 0 {
mask &= ^DV_I_47_2_bit
}
}
if (mask & DV_I_48_2_bit) != 0 {
if not((W[63]^(W[64]>>5))&(1<<2)) != 0 ||
not(not((W[48]^(W[49]<<5))&(1<<6))) != 0 {
mask &= ^DV_I_48_2_bit
}
}
if (mask & DV_I_49_2_bit) != 0 {
if not(not((W[49]^(W[50]<<5))&(1<<6))) != 0 ||
not((W[42]^W[50])&(1<<1)) != 0 ||
not(not((W[39]^(W[40]<<5))&(1<<6))) != 0 ||
not((W[38]^W[40])&(1<<1)) != 0 {
mask &= ^DV_I_49_2_bit
}
}
if (mask & DV_I_50_0_bit) != 0 {
mask &= (((W[36] ^ W[37]) << 7) | ^DV_I_50_0_bit)
}
if (mask & DV_I_50_2_bit) != 0 {
mask &= (((W[43] ^ W[51]) << 11) | ^DV_I_50_2_bit)
}
if (mask & DV_I_51_0_bit) != 0 {
mask &= (((W[37] ^ W[38]) << 9) | ^DV_I_51_0_bit)
}
if (mask & DV_I_51_2_bit) != 0 {
if not(not((W[51]^(W[52]<<5))&(1<<6))) != 0 ||
not(not((W[49]^W[51])&(1<<6))) != 0 ||
not(not((W[37]^(W[37]>>5))&(1<<1))) != 0 ||
not(not((W[35]^(W[39]>>25))&(1<<5))) != 0 {
mask &= ^DV_I_51_2_bit
}
}
if (mask & DV_I_52_0_bit) != 0 {
mask &= (((W[38] ^ W[39]) << 11) | ^DV_I_52_0_bit)
}
if (mask & DV_II_46_2_bit) != 0 {
mask &= (((W[47] ^ W[51]) << 17) | ^DV_II_46_2_bit)
}
if (mask & DV_II_48_0_bit) != 0 {
if not(not((W[36]^(W[40]>>25))&(1<<3))) != 0 ||
not((W[35]^(W[40]<<2))&(1<<30)) != 0 {
mask &= ^DV_II_48_0_bit
}
}
if (mask & DV_II_49_0_bit) != 0 {
if not(not((W[37]^(W[41]>>25))&(1<<3))) != 0 ||
not((W[36]^(W[41]<<2))&(1<<30)) != 0 {
mask &= ^DV_II_49_0_bit
}
}
if (mask & DV_II_49_2_bit) != 0 {
if not(not((W[53]^(W[54]<<5))&(1<<6))) != 0 ||
not(not((W[51]^W[53])&(1<<6))) != 0 ||
not((W[50]^W[54])&(1<<1)) != 0 ||
not(not((W[45]^(W[46]<<5))&(1<<6))) != 0 ||
not(not((W[37]^(W[41]>>25))&(1<<5))) != 0 ||
not((W[36]^(W[41]>>30))&(1<<0)) != 0 {
mask &= ^DV_II_49_2_bit
}
}
if (mask & DV_II_50_0_bit) != 0 {
if not((W[55]^W[58])&(1<<29)) != 0 ||
not(not((W[38]^(W[42]>>25))&(1<<3))) != 0 ||
not((W[37]^(W[42]<<2))&(1<<30)) != 0 {
mask &= ^DV_II_50_0_bit
}
}
if (mask & DV_II_50_2_bit) != 0 {
if not(not((W[54]^(W[55]<<5))&(1<<6))) != 0 ||
not(not((W[52]^W[54])&(1<<6))) != 0 ||
not((W[51]^W[55])&(1<<1)) != 0 ||
not((W[45]^W[47])&(1<<1)) != 0 ||
not(not((W[38]^(W[42]>>25))&(1<<5))) != 0 ||
not((W[37]^(W[42]>>30))&(1<<0)) != 0 {
mask &= ^DV_II_50_2_bit
}
}
if (mask & DV_II_51_0_bit) != 0 {
if not(not((W[39]^(W[43]>>25))&(1<<3))) != 0 ||
not((W[38]^(W[43]<<2))&(1<<30)) != 0 {
mask &= ^DV_II_51_0_bit
}
}
if (mask & DV_II_51_2_bit) != 0 {
if not(not((W[55]^(W[56]<<5))&(1<<6))) != 0 ||
not(not((W[53]^W[55])&(1<<6))) != 0 ||
not((W[52]^W[56])&(1<<1)) != 0 ||
not((W[46]^W[48])&(1<<1)) != 0 ||
not(not((W[39]^(W[43]>>25))&(1<<5))) != 0 ||
not((W[38]^(W[43]>>30))&(1<<0)) != 0 {
mask &= ^DV_II_51_2_bit
}
}
if (mask & DV_II_52_0_bit) != 0 {
if not(not((W[59]^W[60])&(1<<29))) != 0 ||
not(not((W[40]^(W[44]>>25))&(1<<3))) != 0 ||
not(not((W[40]^(W[44]>>25))&(1<<4))) != 0 ||
not((W[39]^(W[44]<<2))&(1<<30)) != 0 {
mask &= ^DV_II_52_0_bit
}
}
if (mask & DV_II_53_0_bit) != 0 {
if not((W[58]^W[61])&(1<<29)) != 0 ||
not(not((W[57]^(W[61]>>25))&(1<<4))) != 0 ||
not(not((W[41]^(W[45]>>25))&(1<<3))) != 0 ||
not(not((W[41]^(W[45]>>25))&(1<<4))) != 0 {
mask &= ^DV_II_53_0_bit
}
}
if (mask & DV_II_54_0_bit) != 0 {
if not(not((W[58]^(W[62]>>25))&(1<<4))) != 0 ||
not(not((W[42]^(W[46]>>25))&(1<<3))) != 0 ||
not(not((W[42]^(W[46]>>25))&(1<<4))) != 0 {
mask &= ^DV_II_54_0_bit
}
}
if (mask & DV_II_55_0_bit) != 0 {
if not(not((W[59]^(W[63]>>25))&(1<<4))) != 0 ||
not(not((W[57]^(W[59]>>25))&(1<<4))) != 0 ||
not(not((W[43]^(W[47]>>25))&(1<<3))) != 0 ||
not(not((W[43]^(W[47]>>25))&(1<<4))) != 0 {
mask &= ^DV_II_55_0_bit
}
}
if (mask & DV_II_56_0_bit) != 0 {
if not(not((W[60]^(W[64]>>25))&(1<<4))) != 0 ||
not(not((W[44]^(W[48]>>25))&(1<<3))) != 0 ||
not(not((W[44]^(W[48]>>25))&(1<<4))) != 0 {
mask &= ^DV_II_56_0_bit
}
}
}
return mask
}
func not(x uint32) uint32 {
if x == 0 {
return 1
}
return 0
}
func SHA1_dvs() []DvInfo {
return sha1_dvs
}

View File

@ -1,12 +0,0 @@
//go:build (!amd64 && !arm64) || noasm || !gc
// +build !amd64,!arm64 noasm !gc
package ubc
// Check takes as input an expanded message block and verifies the unavoidable bitconditions
// for all listed DVs. It returns a dvmask where each bit belonging to a DV is set if all
// unavoidable bitconditions for that DV have been met.
// Thus, one needs to do the recompression check for each DV that has its bit set.
func CalculateDvMask(W [80]uint32) uint32 {
return CalculateDvMaskGeneric(W)
}