قاعدة الشيفرة الجاهزة للكمّ: تحقيق الرشاقة التشفيرية قبل «يوم الكيو» Skip to content
→ العودة إلى المدونة
قاعدة الشيفرة الجاهزة للكمّ: تحقيق الرشاقة التشفيرية قبل «يوم الكيو»

قاعدة الشيفرة الجاهزة للكمّ: تحقيق الرشاقة التشفيرية قبل «يوم الكيو»

كل نظامٍ شحنته يوماً ما يستند إلى الافتراض الهادئ نفسه: أنّ تحليل الأعداد الكبيرة إلى عوامل، وحلَّ مسألة اللوغاريتم المتقطّع على المنحنى الإهليلجي، مسألتان صعبتان. خوارزمية RSA، وECDSA، وECDH، ومصافحة TLS التي تُغلِّف واجهتك البرمجية، ومكتبة JWT التي توقّع جلساتك - كلّها لا تحمل الثِّقل إلا لأنّه لم يَبْنِ أحدٌ بعدُ آلةً تكسر ذلك الافتراض بسرعة.

لكنّ حاسوباً كمّياً بالحجم الكافي سيفعل. ليس اليوم. وربّما ليس هذه السنّة. غير أنّ مجتمع التشفير لا يراهن على ربّما، ولا ينبغي لك أنت الآخر أن تفعل.

وهنا الجزء الذي يأخذ المؤسّسات الهندسيّة على حين غرّة: لحظة وصول تلك الآلة - «يوم الكيو» (Q-Day) - ليست لحظة بدء الترحيل، بل لحظة أن يكون الترحيل قد تأخّر بالفعل كثيراً. فقبل وقت طويل من وجود حاسوب كمّيٍّ ذي صلة تشفيريّة، يكون الخصوم قد سجّلوا حركة مرورك المشفّرة بهدوء، يخزّنونها، وينتظرون. البيانات ذات العمر الافتراضيّ الطويل للسرّية - أسرار الدّول، والسجلّات الصحيّة، ومفاتيح الهويّة، وأيّ شيء تُشفّره ثم تنساه - تُحصَد بالفعل الآن. وحين يصدر الخبر العنوانيّ، تكون البيانات قد خرجت من الباب، بأثر رجعيّ.

لا يمكنك الترقيع بأثر رجعيّ. لا يمكنك إلّا أن تكون جاهزاً قبل. و«الجاهزيّة» ليست استبدالاً وحيداً لخوارزمية؛ إنّها خاصيّةٌ تتعلّق بشكل قاعدة شيفرة. إنّها ما يُسمّى الرشاقة التشفيريّة (cryptographic agility)، ولا يمتلكها تقريباً أيّ فريق.

دعني أُريك ما يتطلّبه بناؤها فعلاً. 🔐


🧱 المشكلة الحقيقيّة: التشفير صمغٌ، لا وحدة

«يوم الكيو» (Q-Day) اختصارٌ لليوم الذي يصبح فيه الحاسوب الكمّيّ ذو الصلة التشفيريّة (CRQC) عمليّاً - كبيراً بما يكفي لتشغيل خوارزميّة شور (Shor) ضدّ مفاتيح RSA وECC الإنتاجيّة. تتراوح تقديرات موعد ذلك بين «بعد عقدٍ من الزمن» و«أقرب ممّا تحبّ»، لكنّ التهديد الفعليّ ليس التاريخ. إنّه «احصدها الآن، فُكّ تشفيرها لاحقاً» (Harvest Now, Decrypt Later - HNDL): الخصوم يسجّلون النصوص المشفّرة اليوم لكسرها حين يلحق بها العتاد. إذا كان يجب أن تبقى بياناتك سرّيّةً بعد يوم الكيو، فالوقت يدور ضدّك منذ الآن.

حين يتخيّل معظم الفرق «ترحيلاً تشفيريّاً»، يتخيّلون استبدال استدعاء مكتبة بآخر. يصبح rsa.Sign هو somethingElse.Sign. بحثٌ واستبدال. سبرنت، أو اثنان.

هذا النموذج الذهنيّ هو سبب فشل الترحيلات.

في قاعدة شيفرة حقيقيّة، التشفير ليس وحدةً. إنّه صمغ. إنّه منتشرٌ عبر مئة سطح، وكلّ سطحٍ يُضمر افتراضاته الهادئة الخاصّة:

  • افتراضات الأحجام. توقيع RSA-2048 طوله 256 بايت. أمّا توقيع ML-DSA-65 (بعد الكمّ) فيبلغ نحو 3.3 كيلوبايت. الكود الذي يُصلِّب صِواناً (buffer) بحجم 256 بايت، أو عمود VARCHAR(512) في قاعدة البيانات لتوقيع، يتحطّم لحظة استبدال الخوارزمية.
  • افتراضات صيغة النقل (wire-format). رموز JWT، وسجلّات TLS، والروابط الموقّعة، والتوقيعات المعتمدة على الترويسات - كلٌّ منها قِيس وعُولج وتحقّق منه مقابل طول توقيع محدّد. التوقيعات بعد الكمّيّة ضخمة. ترويسات HTTP، ورتل الرسائل، وأنواع الأعمدة لديك كلّها تحمل ذلك الافتراض بصمت.
  • افتراضات موضع الاستدعاء. يمتدّ مطوّرٌ إلى crypto/rsa مباشرةً داخل معالِج (handler)، أو خدمة، أو سكربت ترحيل. فتصبح الخوارزميّة مُسمّاةً في 47 مكاناً، لا مركزيّةً في أيٍّ منها، وغير قابلة للاختبار كوحدة.

أغلى ما في الترحيل بعد الكمّيّ ليس الرياضيات الجديدة، بل اكتشافك متأخراً كم مكانٍ ضمّن ثوابت الرياضيات القديمة في نظامك - عروض الأعمدة، وحدود الترويسات، وأحجام المخازن المؤقّتة (buffers)، والاستيرادات المُصلَّبة في الكود. وحين تكتشفها، تكون قد استقرّت في مخطّطات قاعدة البيانات الإنتاجيّة التي لا يمكنك تغييرها دون توقّف الخدمة.

هذا هو الدرس الحقيقيّ: قاعدة الشيفرة القادرة على تغيير تشفيرها ليست قاعدة شيفرةٍ تستخدم تشفيراً جيّداً، بل قاعدة شيفرةٍ يملك تشفيرها مفصلاً (seam). المفصل هو اللعبة كلّها. بدونه، يصبح «بدّل الخوارزميّة» بمثابة «أعد هندسة النظام تحت موعدٍ نهائيّ لا تتحكّم به».

الرشاقة التشفيريّة هي انضباط بناء ذلك المفصل عن قصد، في وقتٍ لا ضغط فيه، بحيث يصبح استبدال الخوارزميات تغييراً في الإعداد (configuration) بدلاً من حالة طوارئ.


🗺️ الخطوة الأولى: جردٌ تشفيريّ (لا يمكنك ترحيل ما لا تراه)

قبل أن يتغيّر سطر كودٍ واحد، تحتاج إلى خريطة. فالترحيل الرشيق مستحيلٌ مقابل شبكة تبعيّات غير مرئيّة.

امشِ في قاعدة الشيفرة وائتلف كل مكانٍ يظهر فيه عنصرٌ تشفيريّ بدائيّ (primitive)، ثم وصِف كلّ واحدٍ بخاصّيتين: الخوارزميّة المستخدمة، ومدّة بقاء البيانات التي يحميها سرّيّةً. هذه المدّة هي ما يخبرك بمدى إلحاح ضرورة نقله.

تجزئة كلمة المرور (password hash) لها عمرٌ قصير - بدّلها، ويتوقّف القديم عن الاهتمام به بسرعة. أمّا مفتاح توقيع جذرٍ في بنية المفاتيح الداخليّة (PKI)، أو أرشيفٌ مشفّر لبيانات المستخدمين الشخصيّة (PII) يُلزِمك القانون بالاحتفاظ به سبع سنوات، أو مفتاح الهويّة طويل الأمد في بروتوكول مراسلتك - فهذه لها أعمارٌ تتجاوز أيّ تقديرٍ معقول ليوم الكيو. هذه هي نقطة تعرّضك لـ HNDL، وهي تنتقل إلى مقدّمة الطابور.

في الممارسة، سيُظهر جردك أربع عائلات من العناصر البدائيّة:

  1. اتفاق المفاتيح / تغليف المفاتيح. الـ ECDH في مصافحة TLS، وتبادل المفاتيح في شبكتك الافتراضيّة الخاصّة (VPN). هذا ما يحمي بياناتك أثناء النقل، وهو الهدف الرئيسيّ لـ HNDL.
  2. التوقيعات الرقميّة. ECDSA/RSA في رموز JWT، وتوقيع الكود، وتوقيع المستندات، وشهادات العميل في mTLS. التوقيعات تتعلّق بـ الموثوقيّة لا بالسرّيّة، لذا فهي أقلّ إلحاحاً من جهة HNDL - لكن في اليوم الذي يستطيع فيه المهاجم تزويرها، يصبح كلّ قرار ثقةٍ تتّخذه موضع شكّ.
  3. التشفير المتماثل. AES-GCM، وChaCha20. هذه لا تُكسَر بخوارزميّة شور بالمعنى الكارثيّ؛ فخوارزميّة غروفر (Grover) تُنصِف أمانها الفعّال. فـ AES-256 يصمد بارتياح؛ أمّا AES-128 فيهبط إلى هامشٍ مُقلق. والحلّ هنا هو رفع حجم المفتاح، لا تغيير النموذج.
  4. التهشير. SHA-2 سليمٌ بعد الكمّ؛ وSHA-1 كان ميتاً أصلاً. هذه في الغالب أعمال صيانة روتينيّة.

ذلك الجرد هو قائمة ترحيلك (backlog). لاحظ أنّه منظّمٌ حسب عمر البيانات، لا حسب موضة الخوارزميّات. هذا هو الترتيب الوحيد المهمّ تحت ضغط HNDL.


🔧 تجريد الشيفرة: مفصلُ الرشاقة في Go

الآن الجزء الذي جئت من أجله: المفصلُ ذاته. المبدأ جملةٌ واحدة - منطق الأعمال يعتمد على قدرة، لا على خوارزميّةٍ أبداً - وهو ثابتٌ في أيّ لغة. وإليه في Go.

أولاً، عرّف القدرة كواجهة (interface). هذا هو السطح التشفيريّ الوحيد الذي سيراه منطق أعمالك على الإطلاق:

// crypto/agility.go
package crypto

import "errors"

// Signer is the agility seam. Anything that can "sign these bytes"
// implements it. Business code depends on this interface — never on
// crypto/rsa, crypto/ecdsa, or any post-quantum library directly.
type Signer interface {
	Algorithm() string                 // e.g. "ecdsa-p256", "ml-dsa-65"
	Sign(message []byte) ([]byte, error)
}

// Verifier is the mirror image for the checking side.
type Verifier interface {
	Algorithm() string
	Verify(message, signature []byte) error
}

// KeyMaterial is opaque to the business layer. It is whatever bytes
// a concrete algorithm needs to build itself. The registry owns parsing.
type KeyMaterial []byte

// SignerFactory builds a Signer from key material. Each algorithm
// registers one. This map is the ONLY place an algorithm is named.
type SignerFactory func(key KeyMaterial) (Signer, error)

var registry = map[string]SignerFactory{}

// Register wires an algorithm name to a factory. Call it from each
// implementation's init(). Adding a new algorithm = one new file.
func Register(name string, f SignerFactory) { registry[name] = f }

// NewSigner is the single entry point. The algorithm is a runtime value
// — a config string, an env var, a flag. Swapping it changes no callers.
func NewSigner(alg string, key KeyMaterial) (Signer, error) {
	f, ok := registry[alg]
	if !ok {
		return nil, errors.New("crypto: unknown algorithm " + alg)
	}
	return f(key)
}

الآن الخوارزميّات الملموسة. كلٌّ منها ملفٌّ قائمٌ بذاته يُسجِّل نفسه ويُحقّق الواجهة نفسها. الموقِّع الكلاسيكيّ اليوم:

// crypto/ecdsa.go
package crypto

import (
	"crypto/ecdsa"
	"crypto/rand"
	"crypto/sha256"
)

func init() { Register("ecdsa-p256", newECDSASigner) }

type ecdsaSigner struct{ priv *ecdsa.PrivateKey }

func newECDSASigner(k KeyMaterial) (Signer, error) {
	priv, err := x509ParseECDSA(k) // helper: bytes -> *ecdsa.PrivateKey
	if err != nil {
		return nil, err
	}
	return &ecdsaSigner{priv: priv}, nil
}

func (s *ecdsaSigner) Algorithm() string { return "ecdsa-p256" }

func (s *ecdsaSigner) Sign(message []byte) ([]byte, error) {
	hash := sha256.Sum256(message)
	return ecdsa.SignASN1(rand.Reader, s.priv, hash[:])
}

والموقِّع بعد الكمّيّ - الواجهة نفسها، وتسجيل init() نفسه، لكن برياضيّاتٍ مختلفة في الأسفل. خوارزميّة ML-DSA المعياريّة وفق NIST (المعروفة سابقاً بـ CRYSTALS-Dilithium، والآن FIPS 204) عبر تنفيذٍ موثوق:

// crypto/mldsa.go
package crypto

import oqs "github.com/open-quantum-safe/liboqs-go/oqs"

func init() { Register("ml-dsa-65", newMLDSASigner) }

type mlDsaSigner struct{ ctx *oqs.Signature }

func newMLDSASigner(k KeyMaterial) (Signer, error) {
	ctx := &oqs.Signature{Name: "ML-DSA-65"}
	if err := ctx.Init(); err != nil {
		return nil, err
	}
	return &mlDsaSigner{ctx: ctx}, nil
}

func (s *mlDsaSigner) Algorithm() string { return "ml-dsa-65" }

func (s *mlDsaSigner) Sign(message []byte) ([]byte, error) {
	return s.ctx.Sign(message, nil) // ~3.3 KB signature, not 64 bytes
}

وهذا هو المكسب. هكذا يبدو منطق أعمالك - ولاحظ ما ليس فيه. لا اسم خوارزميّة. لا استيراد crypto/rsa. لا صِوانٌ بحجمٍ يطابق طول توقيعٍ محدّد. مجرّد القدرة:

// token/issuer.go — the agility seam in action
package token

import "myapp/crypto"

type Issuer struct {
	signer crypto.Signer // injected, algorithm-agnostic
}

func NewIssuer(alg string, key crypto.KeyMaterial) (*Issuer, error) {
	s, err := crypto.NewSigner(alg, key) // config decides the algorithm
	if err != nil {
		return nil, err
	}
	return &Issuer{signer: s}, nil
}

func (i *Issuer) Issue(claims []byte) ([]byte, error) {
	return i.signer.Sign(claims) // business logic never names a cipher
}

الترحيل، حين يأتي، ليس تغييراً في الكود في طبقة الأعمال، بل قيمةً في الإعداد:

# Today
SIGNING_ALGORITHM=ecdsa-p256

# The day you migrate — no business-logic diff, no redeployed handlers
SIGNING_ALGORITHM=ml-dsa-65

هذه هي الرشاقة التشفيريّة. لقد صارت الخوارزميّة مفتاح نشرٍ (deployment knob)، لا التزاماً معمارياً.


🐍 المفصل نفسه في Python

النمط مستقلٌّ عن اللغة. في Python، المفصل هو typing.Protocol - فالكتابة البنيويّة (structural typing) تمنحك التبعيّة نفسها المحايدة تجاه الخوارزميّة دون مراسم وراثة:

# crypto/agility.py
from typing import Protocol

class Signer(Protocol):
    algorithm: str
    def sign(self, message: bytes) -> bytes: ...

# A registry, keyed by the config string. Same idea, different syntax.
_signers: dict[str, type["Signer"]] = {}

def register(name: str):
    def deco(cls):
        _signers[name] = cls
        return cls
    return deco

def build_signer(name: str, key: bytes) -> Signer:
    return _signers[name](key)   # KeyError here is a config bug, not a crash

الموقِّع الكلاسيكيّ:

# crypto/ecdsa.py
from crypto.agility import register, Signer

@register("ecdsa-p256")
class ECDSASigner:
    algorithm = "ecdsa-p256"

    def __init__(self, key: bytes) -> None:
        from cryptography.hazmat.primitives.asymmetric import ec
        self._key = load_ec_private_key(key)

    def sign(self, message: bytes) -> bytes:
        return ec_sign_sha256(self._key, message)

والموقِّع بعد الكمّيّ خلف السطح ذاته، باستخدام oqs-python من مشروع Open Quantum Safe (روابط liboqs):

# crypto/mldsa.py
from crypto.agility import register

@register("ml-dsa-65")
class MLDSASigner:
    algorithm = "ml-dsa-65"

    def __init__(self, key: bytes) -> None:
        import oqs                       # pip install oqs-python
        self._ctx = oqs.Signature("ML-DSA-65", key)

    def sign(self, message: bytes) -> bytes:
        return self._ctx.sign(message)   # same return type, quantum-safe math

يبقى كود الأعمال أعمى عن الاختيار:

signer = build_signer(settings.SIGNING_ALGORITHM, key_material)
signature = signer.sign(payload)   # "ecdsa-p256" today, "ml-dsa-65" tomorrow

سواءٌ مددت يدك إلى واجهة (interface) في Go، أو بروتوكول (Protocol) في Python، أو سمة (trait) في Rust، أو نوعٍ عامّ (generic) في TypeScript - فإنّ الثابت هو نفسه: موضع الاستدعاء يعرف قدرةً، والسجلّ (registry) يعرف خوارزميّةً، ولا شيءٌ بينهما يُصلِّب أيّاً منهما.

كلّ سهمٍ يعبر ذلك المفصل هو مكانٌ تكون فيه الخوارزميّة، في قاعدة شيفرةٍ رشيقة، قيمةَ وقت تشغيل - وفي قاعدة شيفرةٍ هشّة، ثابتاً مُصلَّباً.


🔀 لا تقلب المفتاح: اذهب هجيناً

هذه هي المغري، ما إن تملك المفصل: اقتلع RSA، ألقِ ML-KEM مكانه، اشحنه، انتهى. قاومها.

الخوارزميّات بعد الكمّيّة صغيرة. لقد قامت NIST بتقييس ML-KEM وML-DSA (معيارا FIPS 203 و204، المُنهَيان في 2024) بعد سنواتٍ من التحليل - وما زال فكّ التشفير يفاجئنا؛ فقد كُسِر أحد المرشّحين في الجولة الرابعة (SIKE) بنواة معالِجٍ واحدةٍ في أقلّ من ساعة. أنت لا تراهن على حدّ ثقةٍ إنتاجيٍّ بعنصرٍ بدائيٍّ وليدٍ وحده، ولا تطلب من مستخدميك أن يستوعبوا ذلك الخطر بينما الحقل ما زال يستقرّ.

الجواب الناضج خلال نافذة الانتقال هو التشفير الهجين (hybrid cryptography): ادمج خوارزميّةً كلاسيكيّةً بأخرى بعد كمّيّة، بحيث يكون البناء المُركَّب آمناً ما دام أيٌّ منهما صامداً. فتحصل على عقودٍ من التدقيق في الخوارزميّة الكلاسيكيّة كشبكة أمانٍ تحت المقاومة الكمّيّة.

بالنسبة لتبادل المفاتيح - هدف HNDL أثناء النقل - يعني ذلك اقتران X25519 (كلاسيكيّ) مع ML-KEM-768 (بعد كمّيّ):

// Hybrid key agreement: secure if EITHER the classical or the
// post-quantum assumption survives. This is what production TLS
// is migrating to right now.
import (
	"crypto/ecdh"
	"crypto/mlkem" // Go 1.24+ stdlib (FIPS 203)
)

// classical side — X25519
classic, _ := ecdh.X25519().GenerateKey(rand.Reader)
// post-quantum side — ML-KEM-768
pqDecap, _ := mlkem.GenerateKey768() // *mlkem.DecapsulationKey768
pqCipher, pqShared, _ := pqDecap.Encapsulate() // (Ciphertext768, SharedKey)
// shared secret = KDF(classic_shared || pq_shared) — drop one, keep the other

هذا ليس نظريّاً. إنّه يُشحن بالفعل. فعّل Chrome خوارزميّة X25519MLKEM768 لـ TLS؛ وطرحت Cloudflare تبادل المفاتيح الهجين عبر حافّتها (edge)؛ ويعزّز PQ3 من Apple خدمة iMessage بترقيعٍ دوريٍّ للمفاتيح بعد الكمّيّة؛ وبروتوكول PQXDH من Signal يُطبِّق ML-KEM-1024 فوق مصافحته X3DH. كلّ عملية نشرٍ جادّة تذهب هجيناً أولاً، ونقياً بعد الكمّيّ _لاحقاً»، تحديداً لأنّه لا أحد يريد أن يكتشف بالطريقة الصعبة أنّ خوارزميّةً جديدةً واحدةً كانت تحمل ثغرةً لم يلحظها أحد.

الانضباط الهجين نفسه ينطبق على المفصل الذي بنيناه: دَع السجلّ يُسمّي خوارزميّةً هجينة (x25519-mlkem768) كخيارٍ من الدرجة الأولى، لا كحالةٍ خاصّة. فطبقة الأعمال ما زالت تستدعي واجهةً واحدة؛ والسجلّ يقرّر أنّ المصنَّع سيعيد اليوم بناءً تحته خوارزميّتان. فالرشاقة تعني أنّك تستطيع التقدّم (نحو الهجين) والتراجع (نحو الكلاسيكيّ) دون لمس معالِجٍ واحد.

الدرس للقادة الهندسيّين بنيويّ: الترحيلات الناجحة قابلةٌ للعكس. فالتشفير الهجين يمنحك مساراً قابلاً للعكس. أمّا الاستبدال دفعةً واحدة (big-bang) للخوارزميّة فلا يفعل.


📈 دليل الترحيل (إنّها مشكلةٌ تنظيميّة، لا مشكلة رياضيّات)

مع المفصل في مكانه والجرد مرسوماً، يصبح الترحيل ذاته سلسلةً من الخطوات قليلة الدراما، القابلة للعكس كلٌّ على حدة. إليك الدليل الذي يُبقي الأمر رتيباً (أي متوقّعاً وخالياً من المفاجآت):

  • ابنِ المفصل أولاً، رحِّل ثانياً. أعد هندسة الواجهة عبر كلّ موضع استدعاءٍ قبل أن تصل أيّ خوارزميّةٍ جديدة. وما إن يصبح crypto.NewSigner(alg, key) هو الطريق الوحيد الذي توقّع به قاعدة شيفرة أيّ شيء، حتى يصبح الترحيل الفعليّ إطلاقاً للإعداد (config rollout).
  • قِس للواقع الجديد الآن. دقّق تخزينك وصِيَغ النقل مقابل الأحجام بعد الكمّيّة اليوم - أعمدة التوقيع، وحدود الترويسات، وحدود رسائل الرتل، وميزانيّات طول الرمز. فتوقيع ML-DSA أكبر بنحو 50 ضعفاً من ECDSA-P256. واكتشاف ذلك التصادم في ترحيل قاعدة بياناتٍ رخيص؛ أمّا اكتشافه أثناء إطلاق حالة طوارئ (P0) فليس كذلك.
  • رتّب حسب مدّة بقاء البيانات سرّيّةً، لا حسب موضة الخوارزميّات. انقل الأسرار طويلة الأمد أولاً (المفاتيح الجذر، والأرشيفات المشفّرة، ومفاتيح الهويّة). أمّا البيانات قصيرة الأمد - رموز الجلسات العابرة، وتشفير الذاكرة المؤقّتة (cache) - فلها إلحاحٌ أقلّ بكثير تجاه HNDL ويمكن أن تنتظر.
  • اذهب هجيناً، لا دفعةً واحدة. كلّ خوارزميّةٍ جديدة تحصل على شريكٍ كلاسيكيّ أثناء الانتقال. تشحن x25519-mlkem768، لا ML-KEM عارياً، حتى يحظى الحقل بسنواتٍ من النشر تحته.
  • اختبر التشغيل البَيْني (interop)، لا الصحّة فحسب. أخطاء ما بعد الكمّ تختبئ في عدم تطابق المصافحات والصيَغ عبر التنفيذات. يجب أن تتأكّد مجموعة اختباراتك من التوقيعات واتفاقيّات المفاتيح بين مكتبتك ومكتبةٍ مستقلّة - فالخطأ المتّسق مع ذاته ما زال خطأً.
  • تابع المعايير وسلسلة التوريد لديك. أنهت NIST تقييس FIPS 203 (ML-KEM)، و204 (ML-DSA)، و205 (SLH-DSA) في 2024، مع بقاء FN-DSA (Falcon، FIPS 206) في مرحلة المسوّدة وقت كتابة هذا المقال. ثبّت إصدارات تبعيّاتك التشفيريّة وراقبها. فالخوارزميّة التي تتّخذها معياراً اليوم قد تكون هي التي يُكتَشف فيها ضعفٌ غداً - ومن الأفضل لسجلّك أن يتيح لك التحرّك عنها دون إعادة كتابة.

لاحظ ما لا يطلبه هذا الدليل من مهندسيك: سبرنت ترحيلٍ بطوليّ بكلّ الأيدي مقابل موعدٍ نهائيّ. بل يطلب استثماراً معمارياً لمرةٍ واحدة في المفصل، يتبعه تغييراتٌ تزايديّة، قابلةٌ للشحن باستقلال. هذا هو الفرق بين ترحيلٍ تُنفّذه على جدولك الزمنيّ الخاص، وآخر تُنفّذه عليك دورة أخبار.


🔑 الخلاصة

الفرق التي ستصمد أمام يوم الكيو لن تكون تلك التي اختارت أفضل خوارزميّةٍ بعد كمّيّة. الخوارزميّات هدفٌ متحرّك - تُقيَّس، وتُنشَر، وأحياناً تُكسَر على الملأ. والرهان على جاهزيّتك بأنّك خمّنت الفائز هو رهانٌ على رمي عملةٍ لا يمكنك إعادة رميها.

الفرق التي ستصمد هي تلك التي عاملت التشفير كاهتمامٍ معماريٍّ من الدرجة الأولى يملك مفصلاً: مكاناً تكون فيه الخوارزميّة قيمةَ وقت تشغيل، حيث إضافة شيفرةٍ جديدة هي ملفٌّ واحد وعلمُ (flag) إعدادٍ واحد، حيث لا يُسمّي منطق الأعمال عنصراً بدائيّاً ولو مرّة.

ينبغي أن يكون التشفير قيمةً في الإعداد (configuration)، لا التزاماً. ابنِ المفصل الآن، ما دام لا ضغط ولا موعدٌ نهائيّ، بحيث حين يتعيّن على الخوارزميّة أن تتغيّر - وستتغيّر، أكثر من مرّة، في عمر نظامك - لا يضطرّ المعمار إلى ذلك.

قاعدة الشيفرة التي تصمد أمام يوم الكيو ليست تلك التي تشغّل أحدث خوارزميّة، بل تلك القادرة على التبديل إليها بين عشيّةٍ وضحاها، دون إعادة كتابة، والتبديل من جديد في صباح اليوم التالي. اجعل قاعدتك تلك القاعدة.