{"id":48512937,"url":"https://github.com/jedisct1/go-fast","last_synced_at":"2026-04-07T18:01:08.031Z","repository":{"id":299698118,"uuid":"1003892995","full_name":"jedisct1/go-fast","owner":"jedisct1","description":"A Go implementation of the FAST (Format-preserving encryption And Secure Tokenization) algorithm.","archived":false,"fork":false,"pushed_at":"2026-03-08T21:24:32.000Z","size":110,"stargazers_count":8,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-04-04T02:13:50.456Z","etag":null,"topics":["crypto","encryption","fast","format-preserving","format-preserving-encryption","fpe"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jedisct1.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-06-17T19:55:15.000Z","updated_at":"2026-03-08T21:24:25.000Z","dependencies_parsed_at":"2025-06-17T21:39:17.914Z","dependency_job_id":"7e7ad218-d46f-40c5-a02e-17e86d87ef73","html_url":"https://github.com/jedisct1/go-fast","commit_stats":null,"previous_names":["jedisct1/go-fast"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/jedisct1/go-fast","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jedisct1%2Fgo-fast","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jedisct1%2Fgo-fast/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jedisct1%2Fgo-fast/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jedisct1%2Fgo-fast/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jedisct1","download_url":"https://codeload.github.com/jedisct1/go-fast/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jedisct1%2Fgo-fast/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31522574,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-07T16:28:08.000Z","status":"ssl_error","status_checked_at":"2026-04-07T16:28:06.951Z","response_time":105,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["crypto","encryption","fast","format-preserving","format-preserving-encryption","fpe"],"created_at":"2026-04-07T18:00:48.668Z","updated_at":"2026-04-07T18:01:08.017Z","avatar_url":"https://github.com/jedisct1.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# go-fast\n\nA Go implementation of the FAST (Format-preserving encryption And Secure Tokenization) algorithm.\n\nFAST is a format-preserving encryption (FPE) scheme that encrypts data while preserving its format. A 16-byte input encrypts to a 16-byte output, a sequence of decimal digits stays decimal, and so on. It supports arbitrary alphabets (radix 2--256), making it suitable both for raw byte encryption and for encrypting structured tokens like credit card numbers, API keys, or identifiers over restricted character sets.\n\n## Features\n\n- **Format-preserving encryption**: Output has the same length and alphabet as input\n- **Arbitrary radix**: Supports alphabets from radix 2 (binary) to 256 (bytes)\n- **Cross-language parity**: Produces identical ciphertext as the JavaScript and Python FAST implementations\n- **Secure**: Based on AES with provable security guarantees\n- **Fast**: Optimized implementation with pre-computed S-boxes and efficient diffusion\n- **Deterministic**: Same plaintext + key + tweak always produces the same ciphertext\n- **Tweak support**: Domain separation through optional tweak parameter\n\n## Installation\n\n```bash\ngo get github.com/jedisct1/go-fast\n```\n\n## Usage\n\n### Basic Example\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n    \"github.com/jedisct1/go-fast\"\n)\n\nfunc main() {\n    // Create a new FAST cipher with a 16-byte key (AES-128)\n    key := []byte(\"0123456789abcdef\")\n    cipher, err := fast.NewCipher(key)\n    if err != nil {\n        panic(err)\n    }\n\n    // Encrypt some data\n    plaintext := []byte(\"Hello, World!\")\n    ciphertext := cipher.Encrypt(plaintext, nil)\n    \n    fmt.Printf(\"Plaintext:  %s\\n\", plaintext)\n    fmt.Printf(\"Ciphertext: %x\\n\", ciphertext)\n    \n    // Decrypt it back\n    decrypted := cipher.Decrypt(ciphertext, nil)\n    fmt.Printf(\"Decrypted:  %s\\n\", decrypted)\n}\n```\n\n### Using Tweaks for Domain Separation\n\n```go\n// Different tweaks produce different ciphertexts for the same plaintext\ndata := []byte(\"sensitive data\")\ntweak1 := []byte(\"domain1\")\ntweak2 := []byte(\"domain2\")\n\nciphertext1 := cipher.Encrypt(data, tweak1)\nciphertext2 := cipher.Encrypt(data, tweak2)\n\n// ciphertext1 != ciphertext2\n\n// Must use the same tweak to decrypt\ndecrypted1 := cipher.Decrypt(ciphertext1, tweak1) // ✓ Correct\ndecrypted2 := cipher.Decrypt(ciphertext1, tweak2) // ✗ Wrong result\n```\n\n### Key Sizes\n\nFAST supports AES-128, AES-192, and AES-256:\n\n```go\n// AES-128 (recommended)\nkey128 := make([]byte, 16)\ncipher128, _ := fast.NewCipher(key128)\n\n// AES-192\nkey192 := make([]byte, 24)\ncipher192, _ := fast.NewCipher(key192)\n\n// AES-256\nkey256 := make([]byte, 32)\ncipher256, _ := fast.NewCipher(key256)\n```\n\n### Arbitrary Radix (Non-Byte Alphabets)\n\nFor encrypting data over smaller alphabets -- decimal digits, hex, alphanumeric characters, base64 -- use `NewCipherFromParams` with parameters computed for the target radix and word length. Each element in the input slice must be in `[0, radix)`.\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n    \"github.com/jedisct1/go-fast\"\n)\n\nfunc main() {\n    key := []byte(\"0123456789abcdef\")\n\n    // Encrypt a 16-digit number using radix 10\n    params, err := fast.CalculateRecommendedParams(10, 16)\n    if err != nil {\n        panic(err)\n    }\n    cipher, err := fast.NewCipherFromParams(params, key)\n    if err != nil {\n        panic(err)\n    }\n\n    // Input: digits 0-9 as byte values (not ASCII)\n    digits := []byte{4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}\n    encrypted := cipher.Encrypt(digits, nil)\n\n    fmt.Printf(\"Original:  %v\\n\", digits)\n    fmt.Printf(\"Encrypted: %v\\n\", encrypted) // still 16 digits, each in [0,9]\n\n    decrypted := cipher.Decrypt(encrypted, nil)\n    fmt.Printf(\"Decrypted: %v\\n\", decrypted)\n}\n```\n\nThe parameterized cipher is fixed to a single `(radix, wordLength)` pair. Create one cipher per combination and reuse it across calls. Different radixes produce completely independent S-box pools and round schedules, so a radix-10 cipher and a radix-62 cipher sharing the same key will produce unrelated outputs.\n\n### Token Encryption\n\nThe `tokens` subpackage scans text for API keys and secrets, encrypts them in place while preserving format, and decrypts them back. It recognizes 28 built-in token patterns from GitHub, Stripe, OpenAI, AWS, Slack, SendGrid, and others.\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n    \"log\"\n\n    \"github.com/jedisct1/go-fast/tokens\"\n)\n\nfunc main() {\n    key := []byte(\"0123456789abcdef\") // AES-128\n\n    enc, err := tokens.New(key)\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    text := \"GitHub PAT: ghp_ABCDEFghijklmnopqrstuvwxyz0123456789\"\n\n    encrypted, err := enc.Encrypt(text)\n    if err != nil {\n        log.Fatal(err)\n    }\n    fmt.Println(encrypted) // \"GitHub PAT: ghp_\u003cencrypted-body\u003e\"\n\n    decrypted, err := enc.Decrypt(encrypted)\n    if err != nil {\n        log.Fatal(err)\n    }\n    fmt.Println(decrypted == text) // true\n}\n```\n\nPer-call options let you filter by token type or override the tweak:\n\n```go\n// Encrypt only GitHub tokens, leave others unchanged\nencrypted, _ := enc.Encrypt(text, tokens.WithTypes(\"github-pat\"))\n\n// Use a per-call tweak for domain separation\nencrypted, _ := enc.Encrypt(text, tokens.WithCallTweak([]byte(\"production\")))\n```\n\n`EncryptWithSpans` returns per-token metadata, and `EncryptWithMappings` returns deduplicated plaintext/ciphertext pairs. Token names, alphabets, and ordering match the JavaScript and Python FAST implementations exactly.\n\n## Algorithm Details\n\nFAST is based on the research paper:\n\u003e \"FAST: Secure and High Performance Format-Preserving Encryption and Tokenization\"  \n\u003e https://eprint.iacr.org/2021/1171.pdf\n\n### Key Properties\n\n- **Security**: Provides 128-bit security when used with AES-128\n- **Performance**: Optimized with cached S-boxes and efficient buffer management\n- **Format preservation**: Input length = output length, values stay within the alphabet\n- **Deterministic**: Reproducible encryption for the same inputs\n- **Two construction modes**: `NewCipher(key)` for byte data of any length; `NewCipherFromParams(params, key)` for a fixed radix and word length\n\n### Security Considerations\n\n- Use a cryptographically secure random key\n- Different applications should use different tweaks\n- The same (plaintext, key, tweak) always produces the same ciphertext\n- For probabilistic encryption, include random data in the tweak\n\n## Testing\n\nRun the comprehensive test suite:\n\n```bash\ngo test -v ./...\n```\n\nFor performance benchmarks:\n\n```bash\ngo test -bench=. -benchtime=10s -run=^$\n```\n\nThis implementation is based on the FAST specification and is provided for research and educational purposes.\n\n## References\n\n- [FAST Paper](https://eprint.iacr.org/2021/1171.pdf)\n- [The Next Generation of Performant Data Protection: a New FPE Algorithm](https://insights.comforte.com/the-next-generation-of-performant-data-protection-a-new-fpe-algorithm)\n- [Format-Preserving Encryption](https://en.wikipedia.org/wiki/Format-preserving_encryption)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjedisct1%2Fgo-fast","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjedisct1%2Fgo-fast","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjedisct1%2Fgo-fast/lists"}