fpe

package module
v0.0.0-...-999cebd Latest Latest
Warning

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

Go to latest
Published: Dec 27, 2025 License: MIT Imports: 2 Imported by: 0

README

Format-Preserving Encryption (FPE) for Google Tink

Test

An opinionated Google Tink implementation of Format-Preserving Encryption (FPE) using the FF1 algorithm, as specified in NIST SP 800-38G.

This package provides a first-class Tink primitive that integrates seamlessly with Tink's key management system, following Tink's design patterns and conventions.

Overview

Format-Preserving Encryption (FPE) allows you to encrypt data while preserving its original format. For example, encrypting a Social Security Number 123-45-6789 will produce another value in the same format, such as 972-22-7396, where the hyphens remain in the same positions.

This is particularly useful for:

  • Tokenization: Replacing sensitive data with tokens that look like the original
  • Database encryption: Encrypting data without changing column types or sizes
  • Compliance: Maintaining data formats required by legacy systems

Features

  • NIST SP 800-38G FF1 Algorithm: Full implementation of the standardized FF1 format-preserving encryption
  • First-Class Tink Integration: Native Tink primitive with KeyManager support and keyset.Handle integration
  • Tink Design Patterns: Follows Tink's primitive patterns, similar to DeterministicAEAD
  • Format Preservation: Automatically preserves format characters (hyphens, dots, colons, @ signs, etc.)
  • Alphabet Detection: Automatically detects the character set (numeric, alphanumeric) from input data
  • Deterministic: Same plaintext + tweak + key = same ciphertext (like Tink's DeterministicAEAD)

Installation

go get github.com/vdparikh/fpe

Usage

This package follows Tink's standard pattern: register KeyManager → create keyset handle → get primitive → use it.

package main

import (
	"fmt"
	"log"

	"github.com/google/tink/go/core/registry"
	"github.com/google/tink/go/keyset"
	"github.com/vdparikh/fpe/tinkfpe"
)

func main() {
	// Step 1: Register the FPE KeyManager with Tink's registry
	// In production, do this at application startup
	keyManager := tinkfpe.NewKeyManager()
	if err := registry.RegisterKeyManager(keyManager); err != nil {
		log.Fatalf("Failed to register FPE KeyManager: %v", err)
	}

	// Step 2: Create a keyset handle using KeyTemplate() (one line!)
	// This generates a secure random key automatically (AES-256 by default)
	handle, err := keyset.NewHandle(tinkfpe.KeyTemplate())
	if err != nil {
		log.Fatalf("Failed to create keyset handle: %v", err)
	}

	// Step 3: Get FPE primitive from keyset handle (just like any Tink primitive!)
	tweak := []byte("tenant-1234|customer.ssn")
	primitive, err := tinkfpe.New(handle, tweak)
	if err != nil {
		log.Fatalf("Failed to create FPE primitive: %v", err)
	}

	// Step 4: Use the primitive
	plaintext := "123-45-6789"
	tokenized, err := primitive.Tokenize(plaintext)
	if err != nil {
		log.Fatalf("Failed to tokenize: %v", err)
	}
	fmt.Printf("Tokenized: %s\n", tokenized)

	detokenized, err := primitive.Detokenize(tokenized, plaintext)
	if err != nil {
		log.Fatalf("Failed to detokenize: %v", err)
	}
	fmt.Printf("Detokenized: %s\n", detokenized)
}
Standalone API (For Non-Tink Use Cases)

If you're not using Tink, you can use the standalone API:

package main

import (
	"fmt"
	"log"
	"github.com/vdparikh/fpe"
)

func main() {
	key := []byte("your-encryption-key-32-bytes-long!")
	tweak := []byte("tenant-1234|customer.ssn")
	
	// Create FPE instance (standalone)
	fpeInstance, err := fpe.NewFF1(key, tweak)
	if err != nil {
		log.Fatal(err)
	}
	
	plaintext := "123-45-6789"
	tokenized, err := fpeInstance.Tokenize(plaintext)
	if err != nil {
		log.Fatal(err)
	}
	
	detokenized, err := fpeInstance.Detokenize(tokenized, plaintext, "")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Tokenized: %s, Detokenized: %s\n", tokenized, detokenized)
}

Package Structure

This package follows Tink's organizational patterns:

  • fpe/ (root): High-level API and public interfaces

    • fpe.FPE: Tink-compatible interface (similar to DeterministicAEAD)
    • fpe.NewFF1(): Standalone constructor for non-Tink use cases
  • fpe/tinkfpe/: Tink integration layer

    • tinkfpe.New(): Factory function to create FPE primitives from keyset.Handle
    • tinkfpe.KeyTemplate(): Creates a key template for easy key generation (one line!)
    • tinkfpe.KeyManager: Tink KeyManager implementation for FPE keys
  • fpe/subtle/: Low-level cryptographic primitives

    • Core NIST FF1 algorithm implementation (raw keys)
    • Not intended for direct use by most users

API Reference

tinkfpe.KeyTemplate() *tink_go_proto.KeyTemplate

Creates a key template for FPE FF1 keys. This is the easiest way to generate keys:

handle, err := keyset.NewHandle(tinkfpe.KeyTemplate())

The default template generates AES-256 keys (32 bytes). For different key sizes:

  • tinkfpe.KeyTemplateAES128() - AES-128 (16 bytes)
  • tinkfpe.KeyTemplateAES192() - AES-192 (24 bytes)
  • tinkfpe.KeyTemplateAES256() - AES-256 (32 bytes, recommended)
tinkfpe.NewKeysetHandleFromKey(key []byte) (*keyset.Handle, error)

Creates a keyset handle from a raw key (e.g., from an HSM or custom key management system). This is useful when you have a key from a system that isn't a standard Tink KMS client.

  • key: Raw key bytes (must be 16, 24, or 32 bytes for AES-128, AES-192, or AES-256)
  • Returns: *keyset.Handle or error

Example:

// Get key from your HSM or key management system
hsmKey := []byte{...} // 32-byte key

// Create keyset handle from the raw key
handle, err := tinkfpe.NewKeysetHandleFromKey(hsmKey)
if err != nil {
    log.Fatal(err)
}

// Use it with FPE
primitive, err := tinkfpe.New(handle, []byte("tweak"))

Note: This creates an unencrypted keyset. In production, consider encrypting the keyset before storing it using keyset.Write() with an AEAD.

tinkfpe.New(handle *keyset.Handle, tweak []byte) (fpe.FPE, error)

Creates a new FPE primitive from a Tink keyset handle. This follows Tink's standard pattern.

  • handle: Tink keyset handle (from keyset.NewHandle(tinkfpe.KeyTemplate()), tinkfpe.NewKeysetHandleFromKey(), or KMS)
  • tweak: Public, non-secret value for domain separation (e.g., tenant ID, table name)
  • Returns: fpe.FPE interface (Tink-compatible) or error
fpe.FPE Interface

The fpe.FPE interface follows Tink's primitive pattern, similar to tink.DeterministicAEAD:

type FPE interface {
    Tokenize(plaintext string) (string, error)
    Detokenize(tokenized string, originalPlaintext string) (string, error)
}
  • Tokenize(plaintext string): Encrypts plaintext while preserving format. Deterministic: same input always produces same output.
  • Detokenize(tokenized, originalPlaintext string): Decrypts tokenized value. The originalPlaintext parameter is used for alphabet detection to ensure consistency.
tinkfpe.KeyManager

The KeyManager implements Tink's registry.KeyManager interface, allowing FPE to be registered with Tink's registry:

keyManager := tinkfpe.NewKeyManager()
registry.RegisterKeyManager(keyManager)
Standalone API
fpe.NewFF1(key, tweak []byte) (*fpe.FF1, error)

Creates a new FF1 FPE instance (standalone, not Tink-compatible).

  • key: Encryption key (minimum 16 bytes, preferably 32 bytes for AES-256)
  • tweak: Public, non-secret value for domain separation
  • Returns: *fpe.FF1 instance or error
(*fpe.FF1) Tokenize(plaintext string) (string, error)

Encrypts plaintext using format-preserving encryption.

(*fpe.FF1) Detokenize(tokenized, originalPlaintext, alphabet string) (string, error)

Decrypts tokenized value using format-preserving encryption.

Supported Formats

The FPE implementation automatically handles various data formats:

  • SSN: 123-45-6789
  • Credit Cards: 4532-1234-5678-9010
  • Phone Numbers: 555-123-4567
  • Email Addresses: user@domain.com
  • Dates: 2024-03-15 or 03-15-2024
  • Times: 14:30:45
  • IP Addresses: 192.168.1.1
  • UUIDs: 550e8400-e29b-41d4-a716-446655440000
  • Alphanumeric: ABC123XYZ

Format characters (hyphens, dots, colons, @ signs) are automatically preserved in their original positions.

Algorithm Details

The implementation uses a Feistel network with 10 rounds, following NIST SP 800-38G:

  1. Format Separation: Separates format characters from data characters
  2. Alphabet Detection: Determines the character set (numeric, alphanumeric)
  3. Numeric Conversion: Converts data characters to numeric representation
  4. Feistel Network: Applies 10 rounds of encryption/decryption using AES
  5. Format Reconstruction: Reconstructs the output with format characters preserved

Testing

This package includes comprehensive test coverage:

  • Wycheproof Test Suite: 57+ test cases covering NIST test vectors, edge cases, invalid inputs, and security properties
  • NIST Compliance: All official NIST SP 800-38G test vectors pass
  • Key Manager Tests: Verifies Tink integration with serialized keysets
  • Format Preservation: Tests verify format characters are preserved across various data types
  • Cryptographic Property Tests: Comprehensive tests for collision resistance, bijectivity, key/tweak sensitivity, distribution, and determinism
Test Suites
Wycheproof Test Suite

Validates NIST compliance and edge cases:

go test ./tinkfpe -v -run TestWycheproofVectors
Cryptographic Properties

Tests fundamental cryptographic properties:

go test ./tinkfpe -v -run "TestCollision|TestAvalanche|TestBijectivity|TestKeySensitivity|TestTweakSensitivity|TestDistribution|TestDeterminism"

Test Coverage:

  • Collision Resistance: 1,000+ test cases verifying no two different inputs produce the same output
  • Bijectivity: 10,000 exhaustive tests ensuring one-to-one mapping
  • Key Sensitivity: Verifies different keys produce different outputs
  • Tweak Sensitivity: Verifies different tweaks produce different outputs
  • Distribution: Statistical tests for uniform output distribution
  • Determinism: Ensures same input + key + tweak = same output
  • Avalanche Effect: Verifies small input changes produce different outputs
Performance Benchmarks

Measure performance characteristics:

go test ./tinkfpe -bench=. -benchmem
# run specific benchmarks
go test ./tinkfpe -bench=BenchmarkTokenize -benchmem
go test ./tinkfpe -bench=BenchmarkRoundTrip -benchmem

Benchmark Coverage:

  • Tokenize Performance: Various input sizes (4-20 characters) and formats
  • Detokenize Performance: Decryption performance for different input types
  • Round-Trip Performance: Full encrypt-decrypt cycle timing
  • Key Size Impact: Performance comparison (AES-128, AES-192, AES-256)
  • Tweak Size Impact: Performance with different tweak lengths
  • Concurrent Operations: Parallel execution performance
  • Format Preservation Overhead: Comparison of formatted vs plain inputs
  • Random Inputs: Realistic workload performance

Example benchmark output:

goos: darwin
goarch: arm64
pkg: github.com/vdparikh/fpe/tinkfpe
cpu: Apple M1 Pro
BenchmarkTokenize/Short_4digits-10         	  160856	      6588 ns/op	    9304 B/op	     223 allocs/op
BenchmarkTokenize/Medium_10digits-10       	  126038	     12978 ns/op	   10360 B/op	     267 allocs/op
BenchmarkTokenize/Long_16digits-10         	   51415	     39200 ns/op	   10584 B/op	     294 allocs/op
BenchmarkTokenize/SSN_Format-10            	   87262	     17695 ns/op	   10216 B/op	     260 allocs/op
BenchmarkTokenize/CreditCard_Format-10     	   84694	     29284 ns/op	   10616 B/op	     293 allocs/op
BenchmarkTokenize/Phone_Format-10          	  117447	     11673 ns/op	   10344 B/op	     269 allocs/op
BenchmarkTokenize/Email_Format-10          	   99303	     26869 ns/op	   12248 B/op	     290 allocs/op
BenchmarkTokenize/Alphanumeric_10-10       	   97296	     11716 ns/op	   14536 B/op	     272 allocs/op
BenchmarkTokenize/Alphanumeric_20-10       	   81456	     14477 ns/op	   15120 B/op	     321 allocs/op
BenchmarkDetokenize/Short_4digits-10       	  172839	      6885 ns/op	    9336 B/op	     233 allocs/op
BenchmarkDetokenize/Medium_10digits-10     	  117016	      9398 ns/op	   10504 B/op	     276 allocs/op
BenchmarkDetokenize/SSN_Format-10          	  127899	      9050 ns/op	   10344 B/op	     269 allocs/op
BenchmarkDetokenize/CreditCard_Format-10   	  112522	     10557 ns/op	   10776 B/op	     299 allocs/op
BenchmarkRoundTrip/Short_4digits-10        	   85324	     14701 ns/op	   18696 B/op	     458 allocs/op
BenchmarkRoundTrip/Medium_10digits-10      	   66572	     18124 ns/op	   20832 B/op	     540 allocs/op
BenchmarkRoundTrip/Long_16digits-10        	   55927	     21227 ns/op	   21264 B/op	     586 allocs/op
BenchmarkRoundTrip/SSN_Format-10           	   68120	     17407 ns/op	   20544 B/op	     530 allocs/op
BenchmarkRoundTrip/CreditCard_Format-10    	   57306	     21421 ns/op	   21344 B/op	     584 allocs/op
BenchmarkKeySizes/AES128-10                	  133369	      8690 ns/op	   10312 B/op	     261 allocs/op
BenchmarkKeySizes/AES192-10                	  139310	      8613 ns/op	   10344 B/op	     266 allocs/op
BenchmarkKeySizes/AES256-10                	  133630	      9114 ns/op	   10344 B/op	     265 allocs/op
BenchmarkTweakVariations/Empty-10          	  135694	      8662 ns/op	    9480 B/op	     258 allocs/op
BenchmarkTweakVariations/Short_8bytes-10   	  136832	      8682 ns/op	    9368 B/op	     260 allocs/op
BenchmarkTweakVariations/Medium_16bytes-10 	  131438	      8945 ns/op	   10344 B/op	     268 allocs/op
BenchmarkTweakVariations/Long_32bytes-10   	  136345	      8792 ns/op	   10408 B/op	     254 allocs/op
BenchmarkTweakVariations/VeryLong_64bytes-10         	  126524	      9081 ns/op	   11400 B/op	     259 allocs/op
BenchmarkConcurrent-10                               	  283246	      4410 ns/op	   10392 B/op	     271 allocs/op
BenchmarkRandomInputs-10                             	  134215	      8856 ns/op	   10353 B/op	     267 allocs/op
BenchmarkFormatPreservation/Numeric_Only-10          	  135824	      8937 ns/op	   10392 B/op	     271 allocs/op
BenchmarkFormatPreservation/SSN_Format-10            	  135708	      9046 ns/op	   10232 B/op	     263 allocs/op
BenchmarkFormatPreservation/CreditCard_Format-10     	  113100	     10459 ns/op	   10616 B/op	     293 allocs/op
BenchmarkFormatPreservation/Phone_Format-10          	  132554	      9107 ns/op	   10376 B/op	     270 allocs/op
BenchmarkFormatPreservation/Email_Format-10          	   98970	     11510 ns/op	   12248 B/op	     290 allocs/op
PASS
ok  	github.com/vdparikh/fpe/tinkfpe	49.386s
All Tests

Run all tests (excluding examples):

go test ./tinkfpe/...

Or run tests in the tinkfpe package specifically:

go test ./tinkfpe -v

Requirements

  • Go: 1.18 or later
  • Tink: v1.7.0 or later (for Tink integration)
  • Dependencies: See go.mod for complete dependency list

Thread Safety

The FPE implementation is thread-safe and can be used concurrently by multiple goroutines. Each FF1 instance and fpe.FPE primitive is safe for concurrent use, as operations do not modify internal state.

Note: While individual operations are thread-safe, you should use separate primitive instances for different tweaks or keys to ensure proper domain separation.

Security Considerations

⚠️ Important: See SECURITY.md for comprehensive security guidance, including tweak strategy, domain size considerations, FF1 vs FF3 context, and production deployment best practices.

Quick Summary:

  • Key Management: Always use Tink's key management system (KMS, HSM, etc.) via keyset.Handle. Never use raw []byte keys in production.
  • Tweak Strategy: Use domain-specific, structured tweaks (e.g., "prod|tokenize|ssn|v1"). Include tenant ID for multi-tenant systems. See SECURITY.md for detailed guidance.
  • Key Size: Use at least 32-byte keys (AES-256) for production. The default KeyTemplate() generates AES-256 keys.
  • Domain Size: The implementation enforces a minimum domain size of 1000 (radix^n ≥ 1000) for security. Very small domains will be rejected. See SECURITY.md for details.
  • FF1 Only: This library only implements FF1 (NIST-approved). FF3 is deprecated by NIST and not supported. See SECURITY.md for context.
  • Deterministic Encryption: FF1 is deterministic (same input = same output), which is suitable for tokenization but may not provide semantic security. See SECURITY.md for implications.
  • Tink Integration: Always use encrypted keysets in production. The insecurecleartextkeyset package is only for examples and testing.

Limitations

  • Small Domains: Inputs with very small domain sizes (radix^n < 1000) are rejected for security reasons. This means single-character inputs or very short numeric strings may not be supported.
  • Maximum Input Length: Inputs longer than 100,000 characters are rejected to prevent resource exhaustion. For most use cases, this limit is far beyond practical needs.
  • Alphabet Detection: The implementation automatically detects numeric vs. alphanumeric alphabets. For mixed alphabets or custom character sets, you may need to use the standalone API with explicit alphabet specification.
  • Performance: FPE is computationally more expensive than standard encryption due to the Feistel network and numeric conversions. For high-throughput scenarios, consider performance testing and benchmarking.
  • Deterministic Nature: FF1 is deterministic, which means the same plaintext always produces the same ciphertext. This is ideal for tokenization but may not provide semantic security in all contexts.
  • Memory Usage: Large inputs require significant memory for numeric conversions. Inputs approaching the 100k character limit may require substantial memory.
  • Side-Channel Resistance: This implementation follows NIST SP 800-38G but does not include explicit side-channel countermeasures. For high-security environments, consider additional protections.

Examples

See the examples/ directory for complete working examples:

  • tink_example.go: Demonstrates Tink integration with keyset persistence
  • random.go: Shows random test case generation and validation

Run examples:

go run examples/tink_example.go
go run examples/random.go

Why Tink?

This package is designed as a first-class Tink primitive because:

  1. Secure Key Management: Tink provides secure key management via KMS, HSM, and encrypted keysets. Keys are never exposed as raw []byte in your application code - they're managed through keyset.Handle, reducing the risk of key leakage.

  2. Key Rotation: Tink's keyset system supports seamless key rotation without code changes. You can add new keys to a keyset, mark old keys as deprecated, and Tink automatically uses the primary key while maintaining backward compatibility.

  3. No Raw Keys in Memory: Unlike raw key management, Tink's keyset.Handle abstraction ensures keys are handled securely. Keys can be encrypted at rest, loaded from secure storage (KMS/HSM), and never appear as plain []byte in your application's memory space.

  4. Consistency: Follows the same patterns as other Tink primitives (DeterministicAEAD, AEAD, etc.), making it familiar to Tink users and easy to integrate into existing Tink-based systems.

  5. Security Best Practices: Leverages Tink's battle-tested security practices, including secure key generation, encrypted keyset storage, and protection against common cryptographic pitfalls.

  6. Ecosystem Integration: Works seamlessly with Tink's ecosystem (KMS clients, key templates, encrypted keysets, etc.), allowing you to leverage existing Tink infrastructure and tooling.

Compliance & Standards

This implementation is compliant with:

  • NIST SP 800-38G: Full compliance with the Format-Preserving Encryption standard
  • FF1 Algorithm: Correct implementation of the FF1 Feistel network with 10 rounds
  • Test Vectors: Passes all official NIST test vectors and Wycheproof-style test suite

See REVIEW.md for detailed compliance documentation.

Contributing

Contributions are welcome! Please ensure:

  • All tests pass (go test ./tinkfpe/...)
  • Code follows Go conventions and is properly formatted (gofmt)
  • New features include appropriate tests
  • Documentation is updated for API changes

License

This package is open source. See the main repository for license details.

Documentation

  • FPE Algorithm Guide: Simplified explanation of how FF1 works, with examples and step-by-step walkthroughs
  • Security Guide: Comprehensive security best practices, tweak strategy, domain size considerations, and production deployment guidance
  • NIST Compliance Review: Detailed compliance documentation with NIST SP 800-38G
  • Wycheproof Test Suite: Test suite documentation and structure

References

Documentation

Overview

Package fpe implements Format-Preserving Encryption (FPE) using the FF1 algorithm. FF1 is a NIST-standardized format-preserving encryption algorithm (NIST SP 800-38G).

This package provides a clean, provider-agnostic implementation of FF1 that can be used with any key management system. It preserves the format of input data (e.g., SSN format XXX-XX-XXXX, credit card numbers, email addresses) while encrypting the actual data characters.

The package includes both standalone FF1 implementation and Tink-compatible primitives (see tink.go). While Tink doesn't natively support FPE, this package provides a Tink-compatible interface that follows Tink's design patterns and integrates seamlessly with Tink's key management system.

Example usage:

key := []byte("your-encryption-key-32-bytes-long!")
tweak := []byte("tenant-1234|customer.ssn")

fpe, err := fpe.NewFF1(key, tweak)
if err != nil {
	log.Fatal(err)
}

// Tokenize (encrypt) while preserving format
tokenized, err := fpe.Tokenize("123-45-6789")
if err != nil {
	log.Fatal(err)
}
// tokenized might be "987-65-4321" (same format, different data)

// Detokenize (decrypt) to recover original
plaintext, err := fpe.Detokenize(tokenized, "123-45-6789", "")
if err != nil {
	log.Fatal(err)
}
// plaintext will be "123-45-6789"

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DetermineAlphabet

func DetermineAlphabet(plaintext string) string

DetermineAlphabet determines the alphabet (character set) from the plaintext. Only considers alphanumeric characters (format chars are handled separately).

func NumericToString

func NumericToString(numeric []uint16, alphabet string, length int) string

NumericToString converts a numeric representation back to string based on alphabet. This is a high-level utility function used by the public FPE API.

func ReconstructWithFormat

func ReconstructWithFormat(data string, formatMask []bool, original string) string

ReconstructWithFormat reconstructs a string with format characters in their original positions.

func SeparateFormatAndData

func SeparateFormatAndData(s string) ([]bool, string)

SeparateFormatAndData separates format characters (hyphens, dots, etc.) from data characters. Returns a format mask (true = format char, false = data char) and the data characters only. Format characters include: hyphens (-), dots (.), colons (:), at signs (@), etc.

func StringToNumeric

func StringToNumeric(s, alphabet string) []uint16

StringToNumeric converts a string to a numeric representation based on alphabet. This is a high-level utility function used by the public FPE API.

Types

type FF1

type FF1 struct {
	// contains filtered or unexported fields
}

FF1 implements Format-Preserving Encryption using the FF1 algorithm. FF1 is based on a Feistel network and preserves the format of input data. This is a high-level wrapper around the subtle.FF1 implementation.

func NewFF1

func NewFF1(key, tweak []byte) (*FF1, error)

NewFF1 creates a new FF1 FPE instance with the given key and tweak. The key should be at least 16 bytes (AES-128) or 32 bytes (AES-256). The tweak is a public, non-secret value that ensures different ciphertexts for the same plaintext when the tweak changes.

This function creates a high-level wrapper around the subtle.FF1 implementation. For Tink integration, use tinkfpe.New() instead.

func (*FF1) Detokenize

func (f *FF1) Detokenize(tokenized string, originalPlaintext string, alphabet string) (string, error)

Detokenize decrypts tokenized value using format-preserving encryption. The alphabet parameter should match what was used during tokenization. If empty, it will be determined from the tokenized data (may not match original).

For best results, pass the alphabet determined from the original plaintext.

func (*FF1) Tokenize

func (f *FF1) Tokenize(plaintext string) (string, error)

Tokenize encrypts plaintext using format-preserving encryption. It preserves format characters (hyphens, dots, colons, @ signs, etc.) and only encrypts the alphanumeric data characters.

Returns the tokenized (encrypted) value that maintains the same format as the input.

type FPE

type FPE interface {
	// Tokenize encrypts plaintext using format-preserving encryption.
	// Returns the tokenized (encrypted) value that preserves the format of the input.
	// This is deterministic: same input always produces same output.
	Tokenize(plaintext string) (string, error)

	// Detokenize decrypts tokenized value using format-preserving encryption.
	// The originalPlaintext parameter is used for alphabet detection to ensure consistency.
	// This is the inverse of Tokenize.
	Detokenize(tokenized string, originalPlaintext string) (string, error)
}

FPE is a Tink-compatible interface for Format-Preserving Encryption operations. This follows Tink's primitive pattern, similar to tink.DeterministicAEAD. FPE is deterministic: same plaintext + tweak + key = same ciphertext.

Directories

Path Synopsis
Package subtle provides low-level cryptographic primitives for Format-Preserving Encryption.
Package subtle provides low-level cryptographic primitives for Format-Preserving Encryption.
Package tinkfpe provides Tink integration for Format-Preserving Encryption.
Package tinkfpe provides Tink integration for Format-Preserving Encryption.

Jump to

Keyboard shortcuts

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