feistel

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 14, 2026 License: MIT Imports: 4 Imported by: 0

README

PkgGoDev Coverage License Go Version Tag Go Report Card Issues

feistel

This package implements balanced variant of Feistel network (also known as Feistel cipher) for golang.

TLDR: It takes bytes and hashes them to reversable form

features

  • small api based on standart data types and interfaces
  • additional Block* functions to use it as part of hashing or crypto lib
  • 100% test coverage

caveats

  • all incoming data slices sizes must be rounded up to selected hash size
  • Uint64* methods work with 32 bit hashes only

example

package main

import (
	"fmt"
	"hash"
	"hash/fnv"

	"github.com/google/uuid"
	"github.com/s0rg/feistel"
)

const nRounds = 4

func hashUint64(h hash.Hash, rounds int, value uint64) {
	a, _ := feistel.Uint64Hash(h, rounds, value)
	fmt.Printf("\t%d -> %d\n", value, a)

	h.Reset()

	b, _ := feistel.Uint64Hash(h, rounds, a)
	fmt.Printf("\t%d -> %d\n", a, b)
}

func hashInt64(h hash.Hash, rounds int, value int64) {
	a, _ := feistel.Uint64Hash(h, rounds, uint64(value))
	fmt.Printf("\t%d -> %d\n", value, a)

	h.Reset()

	b, _ := feistel.Uint64Hash(h, rounds, a)
	fmt.Printf("\t%d -> %d\n", a, int64(b))
}

func hashBytes(h hash.Hash, rounds int, value []byte) (rv []byte) {
	a, _ := feistel.BytesHash(h, rounds, value)
	fmt.Printf("\t%v -> %v\n", value, a)

	h.Reset()

	b, _ := feistel.BytesHash(h, rounds, a)
	fmt.Printf("\t%v -> %v\n", a, b)

	return b
}

func main() {
	hash := fnv.New32a()

	fmt.Println("uin64:")
	hashUint64(hash, nRounds, 123456)
	hash.Reset()

	fmt.Println("int64:")
	hashInt64(hash, nRounds, -123456)
	hash.Reset()

	fmt.Println("bytes:")
	id, _ := uuid.NewV7()
	res := hashBytes(hash, nRounds, id[:])
	fmt.Printf("\toriginal : %s\n", id.String())
	fmt.Printf("\tresult   : %s\n", uuid.UUID(res).String())
}

Output:

uin64:
	123456 -> 11152740970488264477
	11152740970488264477 -> 123456
int64:
	-123456 -> 6380474240854226338
	6380474240854226338 -> -123456
bytes:
	[1 156 228 69 159 236 118 49 137 105 96 245 156 183 76 171] -> [217 207 28 95 81 184 4 143 250 166 52 24 222 245 102 47]
	[217 207 28 95 81 184 4 143 250 166 52 24 222 245 102 47] -> [1 156 228 69 159 236 118 49 137 105 96 245 156 183 76 171]
	original : 019ce445-9fec-7631-8969-60f59cb74cab
	result   : 019ce445-9fec-7631-8969-60f59cb74cab

license

MIT

Documentation

Overview

Package feistel implements Feistel network (also kown as Feistel cipher) for bytes slices and integers.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrBadRoundsCount - invalid rounds value.
	ErrBadRoundsCount = errors.New("rounds value must be > 0")

	// ErrUnevenDataSize - incoming data size in not even.
	ErrUnevenDataSize = errors.New("data size must be even")

	// ErrWrongHasherSize - invalid hasher selected for given data size.
	ErrWrongHasherSize = errors.New("wrong hasher size - must be half of data size")
)

Functions

func BytesHash

func BytesHash(hasher hash.Hash, rounds int, data []byte) (rv []byte, err error)

BytesHash runs balanced Feistel network for specified bytes slice.

func BytesHashKeys

func BytesHashKeys(hasher hash.Hash, keys [][]byte, data []byte) (rv []byte, err error)

BytesHashKeys runs balanced Feistel network for specified bytes slice with given set of keys.

func HashBlock

func HashBlock(hasher hash.Hash, rounds int, data []byte) (rv []byte, err error)

HashBlock runs balanced Feistel network for specified bytes block its size must be even and twice of hasher size. Please note - this method damages provided data slice, use this if speed matters but original data content is not.

func HashBlockSafe

func HashBlockSafe(hasher hash.Hash, rounds int, data []byte) (rv []byte, err error)

HashBlockSafe is a safe version of BlockHash method, its slower and uses one more alloc but does not change content of provided data slice, uses this if you need those bytes elsewhere.

func HashBlockUnsafe

func HashBlockUnsafe(hasher hash.Hash, rounds int, data []byte) (rv []byte)

HashBlockUnsafe runs balanced Feistel network for specified bytes slice without any bounds checks.

func HashKeys

func HashKeys(hasher hash.Hash, keys [][]byte, data []byte) (rv []byte, err error)

HashKeys runs balanced Feistel network for specified bytes block with given set of keys. This method damages provided data slice.

func HashKeysSafe

func HashKeysSafe(hasher hash.Hash, keys [][]byte, data []byte) (rv []byte, err error)

HashKeysSafe is a safe version of BlockKeys method - it does not change incoming data slice.

func HashKeysUnsafe

func HashKeysUnsafe(hasher hash.Hash, keys [][]byte, data []byte) (rv []byte)

HashKeysUnsafe runs balanced Feistel network for specified bytes slice with given set of keys without any bounds checks.

func Uint64Hash

func Uint64Hash(hasher hash.Hash, rounds int, value uint64) (rv uint64, err error)

Uint64Hash runs Feistel network for specified integer value.

func Uint64HashKeys

func Uint64HashKeys(hasher hash.Hash, keys [][]byte, value uint64) (rv uint64, err error)

Uint64HashKeys runs Feistel network for specified integer value and set of keys.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL