Skip to content

About

C++23 cryptographic library for Unicode-aware Indic text and format-preserving encryption, with AES-GCM, KDF/HKDF, FPE domains, arbitrary-precision numerals, and an FF1 implementation in active development.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

12 Commits

Folders and files

Repository files navigation

IndicCrypt

IndicCrypt is a C++23 cryptographic library focused on format-preserving encryption (FPE) for Indic-language text.

The project combines:

  • Unicode-aware Indic text processing
  • Script and language-aware symbol modeling
  • Structured encryption domains
  • Modern cryptographic primitives
  • Arbitrary-precision arithmetic
  • FF1 format-preserving encryption

Status: Active development

Current test status: 29/29 tests passing

Language: C++23


Vision

Indic languages have linguistic structures that are not well represented by treating text as arbitrary bytes.

IndicCrypt is designed around a structured representation:

Indic Text
    │
    ▼
Unicode / Grapheme Processing
    │
    ▼
Indic Symbols
    │
    ▼
Language / Script Aware Domain
    │
    ▼
FPE Radix Representation
    │
    ▼
FF1 Format-Preserving Encryption
    │
    ▼
Encrypted Symbol Domain
    │
    ▼
Encrypted Indic Text

The long-term goal is to allow applications to protect sensitive Indic text while preserving its structural representation.


Current Status

IndicCrypt is being developed incrementally through independently tested layers.

Completed

Text foundation

  • Unicode foundation using ICU4C
  • Grapheme processing
  • Indic script model
  • Indic language model
  • IndicSymbol
  • Text canonicalization

Cryptographic foundation

  • Cryptographic byte/key types
  • Key lifecycle primitives
  • KDF
  • HKDF
  • AES block primitives
  • AES-256-GCM

FPE foundation

  • FPE alphabet abstraction
  • FPE codec
  • FPE radix
  • FPE domain
  • FPE parameters
  • Arbitrary-precision FPE numerals
  • FPE numeral mathematics
  • Numeral encoding

FF1 implementation

  • FF1 parameter block (P)
  • FF1 Q block
  • FF1 PRF
  • FF1 Y generation
  • FF1 Y number representation
  • FF1 round value arithmetic
  • FF1 round function
  • 10-round FF1 Feistel construction
  • FF1 encryption
  • FF1 decryption
  • Even-length message handling
  • Odd-length message handling
  • Message-length preservation
  • Radix-domain preservation

FF1 Pipeline

The current FF1 implementation is structured as:

Input
  │
  ▼
FpeParameters
  │
  ├── Domain
  ├── Key
  └── Tweak
  │
  ▼
Initial A / B split
  │
  ▼
┌──────────────────────────────┐
│       FF1 Round 0            │
│                              │
│ P + Q                        │
│   ↓                          │
│ PRF                          │
│   ↓                          │
│ Y                            │
│   ↓                          │
│ NUM(A) ± Y mod radix^m       │
└──────────────────────────────┘
  │
  ▼
Round 1
  │
  ▼
...
  │
  ▼
Round 9
  │
  ▼
Ciphertext

Decryption performs the same construction in reverse order using subtraction.


Format Preservation

FF1 operates on radix values instead of producing arbitrary binary ciphertext.

Conceptually:

Plaintext:

[0, 1, 0, 1, 0]

        │
        ▼
       FF1
        │
        ▼

Ciphertext:

[1, 0, 1, 1, 0]

The ciphertext remains inside the configured radix domain and preserves the original message length.

This property is important for structured data and text domains.


Odd-Length Messages

The implementation explicitly handles odd-length inputs.

Examples currently tested include:

2 digits
3 digits
4 digits
5 digits
6 digits
7 digits
8 digits
9 digits
10 digits

For odd lengths, the FF1 halves alternate in size during the Feistel rounds.

For example, with three digits:

Round 0:

A = 1 digit
B = 2 digits

        ↓

C = 1 digit

        ↓

A = previous B
B = C


Round 1:

A = 2 digits
B = 1 digit

        ↓

C = 2 digits

The implementation preserves the total message length throughout the process.


Architecture

IndicCrypt
│
├── core/
│   ├── crypto/
│   │   ├── AES
│   │   ├── AES-GCM
│   │   ├── KDF
│   │   ├── HKDF
│   │   └── key lifecycle
│   │
│   ├── text/
│   │   ├── canonicalizer
│   │   ├── grapheme
│   │   ├── language
│   │   ├── script
│   │   └── symbol
│   │
│   └── fpe/
│       ├── alphabet
│       ├── codec
│       ├── domain
│       ├── radix
│       ├── parameters
│       ├── numeral
│       ├── numeral math
│       ├── numeral encoding
│       ├── PRF
│       ├── parameter block
│       ├── Q block
│       ├── Y
│       ├── Y number
│       ├── round value
│       ├── round
│       └── FF1
│
├── include/
│   └── indiccrypt/
│       ├── crypto/
│       ├── text/
│       └── fpe/
│
├── tests/
│   ├── crypto/
│   ├── text/
│   └── fpe/
│
└── research/
    ├── crypto-design.md
    ├── search-security.md
    └── threat-model.md

Text Processing Layer

IndicCrypt does not treat Indic text simply as a sequence of bytes.

The text layer provides abstractions for:

  • Unicode-aware processing
  • Grapheme boundaries
  • Script information
  • Language information
  • Canonicalization
  • Structured symbols

The primary symbol abstraction is:

indiccrypt::text::IndicSymbol

A symbol contains:

Symbol ID
Grapheme
Script
Language

This allows the FPE layer to operate on a controlled symbol domain instead of directly operating on arbitrary UTF-8 byte sequences.


FPE Domain

The FPE subsystem separates text representation from mathematical encryption.

IndicSymbol
    │
    ▼
FpeAlphabet
    │
    ▼
FpeCodec
    │
    ▼
FpeRadix
    │
    ▼
FpeDomain
    │
    ▼
FpeParameters
    │
    ▼
Ff1

FpeAlphabet

Defines the symbols belonging to an encryption domain.

FpeAlphabet(
    Script script,
    std::vector<IndicSymbol> symbols,
    std::string version
);

The alphabet provides deterministic symbol-to-index mapping.


FpeCodec

Converts between:

IndicSymbol[]

and:

FpeRadix::Value[]

This separates text representation from the numerical representation used by FF1.


FpeRadix

Represents the numerical domain used by FPE.

Each digit satisfies:

0 <= digit < radix

FpeDomain

Combines:

Alphabet
Codec
Radix

into a single encryption domain.


FpeParameters

Carries the parameters required by FF1:

Domain
Key
Tweak
Length constraints

Arbitrary-Precision Numerals

FF1 requires arithmetic that can exceed native integer sizes.

IndicCrypt therefore uses:

Boost.Multiprecision::cpp_int

through the Ff1Numeral abstraction.

Supported operations include:

toInteger()
fromInteger()
digits()
radix()
size()
empty()

This allows the FPE implementation to operate on radix powers substantially larger than 64-bit integer limits.


FF1 Components

The FF1 implementation is split into small components:

Ff1
 │
 ├── Ff1Numeral
 ├── Ff1NumeralMath
 ├── Ff1NumeralEncoding
 ├── Ff1Prf
 ├── Ff1ParameterBlock
 ├── Ff1QBlock
 ├── Ff1YGenerator
 ├── Ff1YNumber
 ├── Ff1RoundValue
 └── Ff1Round

Each component has its own tests where appropriate.


Testing

IndicCrypt uses CTest with CMake/Ninja.

Current result:

29/29 tests passed

100% tests passed

Total Test time ≈ 13 seconds

Run the complete suite:

ctest --test-dir build --output-on-failure

Run the FF1 integration test:

ctest --test-dir build -R indiccrypt_ff1_tests -V

The FF1 test suite currently verifies:

  • Encryption executes successfully
  • Decryption executes successfully
  • Encryption is deterministic
  • Decryption recovers the original plaintext
  • Ciphertext remains inside the radix
  • Message length is preserved
  • Invalid digits are rejected
  • Even-length messages
  • Odd-length messages
  • Multiple message lengths

Build

Requirements

IndicCrypt currently requires:

  • C++23-compatible compiler
  • CMake
  • Ninja
  • OpenSSL 3
  • ICU4C
  • Boost

The project is currently developed and tested on macOS.

Configure

cmake -S . -B build -G Ninja

Build

cmake --build build

Test

ctest --test-dir build --output-on-failure

Dependencies

OpenSSL

Used for cryptographic primitives and AES-GCM.

ICU4C

Used for Unicode-aware text processing.

Boost.Multiprecision

Used for arbitrary-precision arithmetic required by the FPE implementation.


Development Workflow

IndicCrypt is intentionally being built in independently tested milestones.

Current progression:

Unicode foundation
        ↓
Indic text model
        ↓
Cryptographic primitives
        ↓
FPE domain
        ↓
Arbitrary-precision numerals
        ↓
FF1 infrastructure
        ↓
P block
        ↓
Q block
        ↓
PRF
        ↓
Y generation
        ↓
FF1 round arithmetic
        ↓
Complete FF1
        ↓
Indic text integration
        ↓
Known-answer vectors
        ↓
Differential testing
        ↓
Security review

The major difference from earlier stages is that the FF1 encryption/decryption engine is now implemented and passing its integration tests.


Security

Security is a primary design goal.

The repository contains ongoing security and design documentation:

research/crypto-design.md
research/search-security.md
research/threat-model.md

However:

IndicCrypt is experimental software and should not yet be used to protect production secrets.

Passing 29/29 unit and integration tests does not constitute cryptographic validation.

Before a production release, the project still requires:

  • Official FF1 known-answer test vectors
  • Differential/interoperability testing
  • Extensive boundary testing
  • Fuzz testing
  • Security review
  • Cryptographic review
  • API review
  • Key-management review
  • Performance benchmarking

Design Principles

1. Structured text

Indic text is represented through language, script, grapheme, and symbol abstractions.

2. Separation of concerns

Text processing, domain encoding, cryptography, and FPE mathematics remain separate layers.

3. Established cryptography

Established cryptographic primitives such as OpenSSL are preferred where appropriate.

4. Explicit validation

Invalid keys, lengths, radix digits, and numerical values are rejected explicitly.

5. Arbitrary precision

FPE arithmetic should not be artificially constrained by native integer sizes.

6. Test-driven development

Major subsystems are introduced with independent tests.

7. No premature production claims

Passing tests is a milestone, not proof that a cryptographic implementation is ready for production.


Roadmap

Phase 1 — Foundation

  • Repository structure
  • CMake build system
  • ICU4C integration
  • Unicode foundation
  • Indic text model
  • Text canonicalization

Phase 2 — Cryptography

  • Crypto types
  • Key lifecycle
  • KDF
  • HKDF
  • AES block primitive
  • AES-256-GCM
  • Expanded cryptographic validation

Phase 3 — FPE Domain

  • Alphabet
  • Codec
  • Radix
  • Domain
  • Parameters
  • Numeral representation
  • Numeral mathematics
  • Numeral encoding

Phase 4 — FF1

  • FF1 API
  • FF1 PRF
  • FF1 P block
  • FF1 Q block
  • Y generation
  • Y number representation
  • Round value arithmetic
  • FF1 round function
  • FF1 encryption
  • FF1 decryption
  • Even-length handling
  • Odd-length handling
  • Official FF1 known-answer vectors
  • Differential/interoperability testing

Phase 5 — Indic FPE

  • Indic alphabet registry
  • Language-specific domains
  • Script-specific domains
  • Grapheme-preserving encryption
  • Indic text encryption API
  • Indic text decryption API
  • End-to-end Indic text tests

Phase 6 — Security & Release

  • Extensive negative testing
  • Fuzz testing
  • Differential testing
  • Performance benchmarks
  • Security review
  • API stabilization
  • Documentation
  • Release candidate

Project Status

Current milestone:  FF1 implementation

Tests:              29 / 29
Build:              Passing
Text foundation:    Complete
Crypto foundation:  Complete
FPE foundation:     Complete
FF1 rounds:         Complete
FF1 encryption:     Complete
FF1 decryption:     Complete

Known-answer tests: Pending
Indic text API:     Pending
Security review:    Pending
Production ready:   No

License

License information will be added as the project approaches its first public release.


This version matches your **actual current milestone**: the FF1 engine is no longer merely “in development”; you have reached **29/29 passing tests**. Your uploaded README's old 25/25 status and “FF1 implementation still being implemented” section are now stale. :contentReference[oaicite:1]{index=1}

About

C++23 cryptographic library for Unicode-aware Indic text and format-preserving encryption, with AES-GCM, KDF/HKDF, FPE domains, arbitrary-precision numerals, and an FF1 implementation in active development.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages