debian-python-cryptography/docs/development/custom-vectors/arc4/verify_arc4.go

112 lines
2.6 KiB
Go

package main
import (
"bufio"
"bytes"
"crypto/rc4"
"encoding/hex"
"fmt"
"os"
"strconv"
"strings"
)
func unhexlify(s string) []byte {
bytes, err := hex.DecodeString(s)
if err != nil {
panic(err)
}
return bytes
}
type vectorArgs struct {
count string
offset uint64
key string
plaintext string
ciphertext string
}
type vectorVerifier interface {
validate(count string, offset uint64, key, plaintext, expectedCiphertext []byte)
}
type arc4Verifier struct{}
func (o arc4Verifier) validate(count string, offset uint64, key, plaintext, expectedCiphertext []byte) {
if offset%16 != 0 || len(plaintext) != 16 || len(expectedCiphertext) != 16 {
panic(fmt.Errorf("Unexpected input value encountered: offset=%v; len(plaintext)=%v; len(expectedCiphertext)=%v",
offset,
len(plaintext),
len(expectedCiphertext)))
}
stream, err := rc4.NewCipher(key)
if err != nil {
panic(err)
}
var currentOffset uint64 = 0
ciphertext := make([]byte, len(plaintext))
for currentOffset <= offset {
stream.XORKeyStream(ciphertext, plaintext)
currentOffset += uint64(len(plaintext))
}
if !bytes.Equal(ciphertext, expectedCiphertext) {
panic(fmt.Errorf("vector mismatch @ COUNT = %s:\n %s != %s\n",
count,
hex.EncodeToString(expectedCiphertext),
hex.EncodeToString(ciphertext)))
}
}
func validateVectors(verifier vectorVerifier, filename string) {
vectors, err := os.Open(filename)
if err != nil {
panic(err)
}
defer vectors.Close()
var segments []string
var vector *vectorArgs
scanner := bufio.NewScanner(vectors)
for scanner.Scan() {
segments = strings.Split(scanner.Text(), " = ")
switch {
case strings.ToUpper(segments[0]) == "COUNT":
if vector != nil {
verifier.validate(vector.count,
vector.offset,
unhexlify(vector.key),
unhexlify(vector.plaintext),
unhexlify(vector.ciphertext))
}
vector = &vectorArgs{count: segments[1]}
case strings.ToUpper(segments[0]) == "OFFSET":
vector.offset, err = strconv.ParseUint(segments[1], 10, 64)
if err != nil {
panic(err)
}
case strings.ToUpper(segments[0]) == "KEY":
vector.key = segments[1]
case strings.ToUpper(segments[0]) == "PLAINTEXT":
vector.plaintext = segments[1]
case strings.ToUpper(segments[0]) == "CIPHERTEXT":
vector.ciphertext = segments[1]
}
}
if vector != nil {
verifier.validate(vector.count,
vector.offset,
unhexlify(vector.key),
unhexlify(vector.plaintext),
unhexlify(vector.ciphertext))
}
}
func main() {
validateVectors(arc4Verifier{}, "vectors/cryptography_vectors/ciphers/ARC4/arc4.txt")
fmt.Println("ARC4 OK.")
}