**HC-128** הוא צופן זרם סינכרוני מותאם במיוחד לתוכנה שפותח ב-2004 על ידי Hongjun Wu אוניברסיטת לוון, הוצע לפרויקט eSTREAM ונבחר כצופן זרם מועדף בקטגוריית תוכנה יחד עם מבחר אלגוריתמים נוספים. הצופן מקבל מפתח בגודל 128 סיביות ווקטור אתחול בגודל 128 סיביות. המצב הפנימי (internal state) של הצופן מורכב משתי טבלאות כל אחת בגודל 512 אוגרים בגודל 32 סיביות. בכל צעד, אוגר אחד באחת הטבלאות מעודכן באמצעות פונקציית הזנה אי-ליניארית והפלט בגודל 32 סיביות נוצר על ידי פונקציית סינון אי-ליניארית. אפשר לייצר זרם מפתח בגודל מרבי של {\displaystyle 2^{64}} סיביות. המסר מוצפן ומפוענח באמצעות XOR עם זרם המפתח.

מפתח הצופן מציין את ההצהרות הבאות: מחזוריות הצופן היא לכל היותר {\displaystyle 2^{128}}. שחזור מפתח ההצפנה קשה כחיפוש ממצה. התקפת הבחנה (distinguishing attack) דורשת לפחות {\displaystyle 2^{64}} סיביות מפתח. לא קיימים מפתחות הצפנה חלשים. הצופן אינו מוגן בפטנט כלשהו. מהירות ההצפנה היא בערך 3.05 מחזורי שעון לבית על מחשב פנטיום.

HC-128 הוא גרסה פשוטה של צופן HC-256 והוא פשוט ומהיר בתוכנה, מנצל את יכולות המעבד המודרני ומאפשר מקביליות, פונקציית ההזנה ופונקציית הפלט יכולות להתבצע בו זמנית.

תיאור הצופן
-----------

סימנים מוסכמים:

|  |  |
| --- | --- |
| {\displaystyle x+y} | {\displaystyle (x+y){\text{ mod }}2^{32}} כאשר {\displaystyle 0\leq x,y<2^{32}}. |
| {\displaystyle x\boxminus y} | {\displaystyle (x-y){\text{ mod }}2^{9}}, למשל {\displaystyle 2-10=504}. |
| {\displaystyle \oplus } | XOR |
| {\displaystyle \|} | שרשור. למשל אם {\displaystyle a=1011} ו-{\displaystyle b=1001}, שרשור המחרוזות יחד הוא {\displaystyle a\ \|\ b=10111001}. |
| {\displaystyle x\gg n} | אופרטור הזזה לימין (shift left) של הסיביות המשתנה {\displaystyle x} בסך הכול {\displaystyle n} צעדים, כאשר הסיביות המשמעותיות מאופסות. |
| {\displaystyle x\ll n} | אופרטור ההזזה לשמאל {\displaystyle n} צעדים כך ש-{\displaystyle n} הסיביות הפחות משמעותיות מאופסות. |
| {\displaystyle x\ggg n} | אופרטור הזזה מעגלית (rotate) לימין על מילים באורך 32 סיביות. הסיביות של {\displaystyle x} מוזזות לימין {\displaystyle n} צעדים כאשר כל הסיביות שנפלטות מצד ימין מוחזרות מצד שמאל. בניסוח פורמלי {\displaystyle ((x\gg n)\oplus (x\ll {(32-n)})} |
| {\displaystyle x\lll n} | הזזה מחזורית לשמאל. בניסוח פורמלי {\displaystyle ((x\ll n)\oplus (x\gg {(32-n)})} |

וקטור האתחול {\displaystyle IV} והמפתח הסודי {\displaystyle K} המסופקים על ידי המשתמש כל אחד בגודל 128 סיביות וכן זיכרון בכמות של שתי טבלאות {\displaystyle P} ו-{\displaystyle Q} כל אחת בגודל 512 אלמנטים של 32 סיביות. זרם המפתח המשמש להצפנה נקרא {\displaystyle s}. והוא שרשור של ערכי 32 סיביות {\displaystyle s\_{0}\ \|\ s\_{1}\ \|\ s\_{2}\ \|\ ...\ } שמופקים בכל צעד.

ישנן 6 פונקציות עזר בצופן. הפונקציות {\displaystyle f\_{1}(x)} ו-{\displaystyle f\_{2}(x)} שאולות מפונקציות דומות שהן חלק מפונקציית התמצות של SHA-2. לצורך הפונקציה {\displaystyle h\_{1}(x)} משתמשים בטבלה {\displaystyle Q} כתיבות החלפה (s-box) ועבור הפונקציה {\displaystyle h\_{2}(x)} משתמשים בטבלה {\displaystyle P}. הפונקציות הן:

{\displaystyle f\_{1}(x)=(x\ggg 7)\oplus (x\ggg {18})\oplus (x\gg 3)}
{\displaystyle f\_{2}(x)=(x\ggg {17})\oplus (x\ggg {19})\oplus (x\gg {10})}
{\displaystyle g\_{1}(x,y,z)=((x\ggg {10})\oplus (x\ggg {23}))+(y\ggg 8)}
{\displaystyle g\_{2}(x,y,z)=((x\lll {10})\oplus (z\lll {23}))+(y\lll 8)}
{\displaystyle h\_{1}(x)=Q[x\_{0}]+Q[256+x\_{2}]}
{\displaystyle h\_{2}(x)=P[x\_{0}]+P[256+x\_{2}]}

כאשר {\displaystyle x=x\_{0}\ \|\ x\_{1}\ \|\ x\_{2}\ \|\ x\_{3}} הוא מילה בגודל 32 סיביות והאלמנטים {\displaystyle x\_{i}} הם ארבעת הבתים המרכיבים את המילה לפי סדר בתים קטן. כאשר בית אפס מייצג את החלק הפחות משמעותי של המילה.

תהליך אתחול
-----------

תהליך האתחול של הצופן כולל הרחבת וקטור האתחול והמפתח הסודי לשתי הטבלאות {\displaystyle P} ו-{\displaystyle Q} בדומה ל-SHA-256. ואז מריצים את הצופן 1024 צעדים בהם לא משתמשים בפלט הצופן כמפתח אלא הפלט מוזן בחזרה לעדכון אלמנטים בטבלאות.
יהי {\displaystyle K=K\_{0}\ \|\ K\_{1}\ \|\ K\_{2}\ \|\ K\_{3}} וכן {\displaystyle IV=IV\_{0}\ \|\ IV\_{1}\ \|\ IV\_{2}\ \|\ IV\_{3}} כאשר כל {\displaystyle K\_{i}} ו-{\displaystyle IV\_{i}} בגודל 32 סיביות. משכפלים את המפתח ווקטור האתחול ארבע פעמים בניסוח פורמלי: {\displaystyle K\_{i+4}=K\_{i}} ו-{\displaystyle IV\_{i+1}=IV\_{i}} עבור {\displaystyle 0\leq i<4}. המפתח ווקטור האתחול מורחבים למערך עזר זמני {\displaystyle W} בגודל 1280 אלמנטים של 32 סיביות כדלהלן:

{\displaystyle W\_{i}={\begin{cases}K\_{i},&0\leq i\leq 7\\IV\_{i-8},&8\leq i\leq 15\\f\_{2}(W\_{i-2})+W\_{i-7}+f\_{1}(W\_{i-15})+W\_{i-16}+i,&16\leq i\leq 1279\end{cases}}}

מעדכנים את הטבלאות כדלהלן: עבור {\displaystyle i=0} עד {\displaystyle 511} בצע: {\displaystyle P[i]=W\_{i+256},Q[i]=W\_{i+768}}. מריצים את הצופן 1024 צעדים כדלהלן:

{\displaystyle {\text{If }}i=0{\text{ to }}511{\text{ do }}}
{\displaystyle P[i]=(P[i]+g\_{1}(P[i\boxminus 3],P[i\boxminus 10],P[i\boxminus 511]))\oplus h\_{1}(P[i\boxminus 12])}
{\displaystyle {\text{If }}i=0{\text{ to }}511{\text{ do }}}
{\displaystyle Q[i]=(Q[i]+g\_{2}(Q[i\boxminus 3],Q[i\boxminus 10],Q[i\boxminus 511]))\oplus h\_{2}(Q[i\boxminus 12])}

בשלב זה הצופן מוכן לשימוש.

הצפנה ופענוח
------------

הצפנה ופענוח זהים כמו בכל צופן זרם, תחילה מייצרים זרם מפתח באורך המסר המיועד להצפנה ואז מבצעים XOR מילה אחר מילה של כל המסר עם זרם המפתח. המחולל המייצר את זרם המפתח מעדכן בכל צעד אלמנט אחד מהטבלאות וכן מפיק פלט של 32 סיביות כחלק מזרם המפתח. כל תיבת החלפה מתוך הטבלאות משמשת להפקת 512 פלטים בלבד ולאחר מכן מתעדכנת לצורך 512 הפלטים הבאים. להלן פסאודו קוד המתאר את מהלכי מחולל זרם המפתח בכל צעד או פעימה. שומרים מונה {\displaystyle i} שמתחיל באפס ומקודם אחרי כל ריצה של המחולל:

1. {\displaystyle j=i{\text{ mod }}512}
2. {\displaystyle {\text{If }}(i{\text{ mod }}1024)<512{\text{ then do }}}
{\displaystyle P[j]=P[j]+g\_{1}(P[i\boxminus 3],P[j\boxminus 10],P[j\boxminus 511])}
{\displaystyle s\_{i}=h\_{1}(P[j\boxminus 12])\oplus P[j]}
3. {\displaystyle {\text{Else do }}}
{\displaystyle Q[j]=Q[j]+g\_{2}(Q[j\boxminus 3],Q[j\boxminus 10],Q[j\boxminus 511])}
{\displaystyle s\_{i}=h\_{2}(Q[j\boxminus 12])\oplus Q[j]}
4. {\displaystyle i=i+1}

הפלט הוא {\displaystyle s\_{i}}. חוזרים על תהליך זה שוב ושוב עד שמתקבל זרם מפתח באורך הרצוי, עד לאורך מקסימלי של {\displaystyle 2^{64}} סיביות או {\displaystyle 2^{59}} מילים. לאחר מכן רצוי להחליף וקטור אתחול או מפתח.

ביטחון
------

פונקציות הפלט וההזנה של הצופן הן בעלי תכונת אי-ליניאריות גבוהה, לכן התקפת קורלציה והתקפה אלגברית אינן ישימות כנגד צופן זה. בנוסף הטבלאות מתעדכנות בזמן ריצה לכן קשה לפתח יחס ליניארי כלשהו בין הקלט לפלט של תיבות ההחלפה. מצב הצופן מכיל בסך הכול 32,778 סיביות, כך שהוא מכיל מחזוריות גבוהה למדי, אם כי קשה להעריכה במדויק. בממוצע מדובר על {\displaystyle 2^{256}} סיביות. כן המספר הגדול של מצבי צופן, מסכל התקפת איזון זמן/זיכרון/דטה כנגד צופן זרם.

אף על פי שפונקציית הפלט האי-ליניארית מדליפה מעט מידע בכל צעד, פונקציית ההזנה מבטיחה שלא ניתן יהיה לנצל מידע זה כדי לשחזר את המפתח הסודי. בשלב האתחול הושם דגש על פיזור טוב והשפעה של סיביות המפתח ווקטור האתחול על כל סיביות טבלאות המצב הפנימי, כדי למנוע התקפה דיפרנציאלית.

קוד לדוגמה
----------

```
typedef struct { 
 uint P[512];
 uint Q[512];
 uint counter1024; // counter1024 = i mod 1024
 uint keystreamword;
} HC128\_State;

#define ROTR32(x,n) ( ((x) >> (n)) | ((x) << (32 - (n))) )
#define ROTL32(x,n) ( ((x) << (n)) | ((x) >> (32 - (n))) )

#define f1(x) (ROTR32((x),7) ^ ROTR32((x),18) ^ ((x) >> 3))
#define f2(x) (ROTR32((x),17) ^ ROTR32((x),19) ^ ((x) >> 10))

uint h1(HC128\_State \*state, uint u) {
 return state->Q[u]+state->Q[256+(u >> 16)];
}

uint h2(HC128\_State \*state, uint u) { 
 return state->P[u]+state->P[256+(u >> 16)];
}

void OneStep(HC128\_State \*state) 
{
 uint i = state->counter1024 & 0x1ff;
 uint i3 = (i - 3) & 0x1ff;
 uint i10 = (i - 10) & 0x1ff;
 uint i12 = (i - 12) & 0x1ff;
 uint i511 = (i - 511) & 0x1ff;

 if (state->counter1024 < 512) {
 state->P[i] = state->P[i] + g1(state->P[i3], state->P[i10], state->P[i511]);
 state->keystreamword = h1(state, state->P[i12]) ^ state->P[i];
 // state->P[i] = h1(state,state->P[i12]) ^ state->P[i]; // replace with this for init
 }
 else {
 state->Q[i] = state->Q[i] + g2(state->Q[i3], state->Q[i10], state->Q[i511]);
 state->keystreamword = h2(state, state->Q[i12]) ^ state->Q[i];
 // state->Q[i] = h2(state,state->Q[i12]) ^ state->Q[i]; // replace with this for init
 }
 state->counter1024 = (state->counter1024+1) & 0x3ff;
}

void Initialization(HC128\_State \*state, byte \*key, byte \*iv) 
{
 uint W[1024+256],i;

 for (i = 0; i < 4; i++) {
 W[i] = ((uint\*)key)[i]; W[i+4] = ((uint\*)key)[i];
 }
 for (i = 0; i < 4; i++) {
 W[i+8] = ((uint\*)iv)[i]; W[i+12] = ((uint\*)iv)[i];
 }

 for (i = 16; i < 1024+256; i++) 
 W[i] = f2(W[i-2]) + W[i-7] + f1(W[i-15]) + W[i-16]+i;

 for (i = 0; i < 512; i++) state->P[i] = W[i+256];
 for (i = 0; i < 512; i++) state->Q[i] = W[i+256+512];

 state->counter1024 = 0;

 for (i = 0; i < 1024; i++) InitOneStep(state); // see comment
}

void EncryptMessage(HC128\_State \*state, byte \*message, byte \*ciphertext, long msglength)
{
 uint64 i;
 uint j;
 
 for (i = 0; (i+4) <= msglength; i += 4, message += 4, ciphertext += 4) 
 {
 OneStep(state); 
 ((uint\*)ciphertext)[0] = ((uint\*)message)[0] ^ state->keystreamword; 
 }
 
 if ((msglength & 3) != 0)
 {
 OneStep(state);
 for (j = 0; j < (msglength & 3); j++) {
 \*(ciphertext+j) = \*(message+j) ^ ((byte\*)&state->keystreamword)[j];
 }
 } 
}

```

הערה: הפונקציה OneStep בשלב האתחול זהה למעט שתי שורות המסומנות בהערה, יש להחליף את השורות הללו בשורות שלפניהן ולקרוא לפונקציה בהתאם InitOneStep (הפונקציה הושמטה כאן מטעמי חסכון מקום).

הערות שוליים
------------

1. ↑  HC-128

| קריפטוגרפיה |
| --- |
| 

| מושגי יסוד |
| --- |
| פנקס חד-פעמי • צופן בלוקים • צופן בלוקים בר התאמה • צופן זרם • סודיות מושלמת • ביטחון סמנטי • הצפנה סימטרית • הצפנה אסימטרית • חתימה דיגיטלית • הצפנה הומומורפית • הצפנה מרובה • הצפנה מאומתת • הצפנה הסתברותית • סכמת ריפוד אסימטרית אופטימלית • אריזת מפתח הצפנה • סודיות מושלמת קדימה |

 |
| 

| הצפנה קלאסית |
| --- |
| מכונת הצפנה • צופן החלפה • צופן אתב"ש • צופן קיסר • צופן ויז'נר • צופן ורנם • צופן פלייפייר • צופן היל • אולטרה • אניגמה • ציקלומטר • קולוסוס • PURPLE • ג'ייד • מג'יק • צופן שחלוף |

 |
| 

| צופן בלוקים |
| --- |
| לוציפר • AES • 3DES • DES • Threefish • Twofish • Blowfish • FEAL • SEED • CAST • IDEA • RC2 • RC6 • MARS • RC5 • GOST • סרפנט • MISTY • KASUMI • קמליה • ARIA • SAFER • TEA • LEA • CLEFIA • SEA • Hummingbird • PRESENT • KATAN • KeeLoq • Simon & Speck • אנוביס |

 |
| 

| אופני הפעלה |
| --- |
| אופן הפעלה של צופן בלוקים • EAX • OCB • IAPM • CWC mode • GCM • CCM |

 |
| 

| צופן זרם |
| --- |
| RC4 • Salsa20 • SOSEMANUK • גריין • E0 • A5/1 • A5/2 • A5/3 • A5/4 • MICKEY • HC-128 • SNOW • Trivium • Rabbit • ZUC • ChaCha |

 |
| 

| הצפנה אסימטרית |
| --- |
| פרוטוקול דיפי-הלמן • חידות מרקל • חתימת למפורט • הצפנת תרמיל • RSA • הצפנת רבין • חתימה דיגיטלית רבין • צופן אל-גמאל • חתימה דיגיטלית אל-גמאל • DSA • הצפנת בלום-גולדווסר • ECC • הצפנת קריימר-שופ • הצפנת פאיי • הצפנת מקאליס • GGH • NTRU • עקום 25519 • חתימה דיגיטלית של שנור • הצפנת אוקמוטו-אושיאמה |

 |
| 

| פרוטוקולים |
| --- |
| עץ מרקל • פרוטוקול אתגר-מענה • פרוטוקול נידהאם-שרודר • פרוטוקול קרברוס • הוכחה באפס ידע • פרוטוקול פייגה-פיאט-שמיר • העברה עלומה • חלוקת סוד • TLS (SSL) • Secure Shell • MQV • X.509 • פרוטוקול שיתוף מפתח
• מיסור שלא לפרסום • פרוטוקול סיגנל |

 |
| 

| פרימיטיבים תאורטיים |
| --- |
| מחולל פסבדו-אקראי קריפטוגרפי • פונקציה חד-כיוונית • תמורה חד-כיוונית • סיבית קשה • פונקציה פסבדו-אקראית קריפטוגרפית • תמורה פסאודו-אקראית • פונקציית גיבוב קריפטוגרפית • וקטור אתחול • פונקציית ספוג • הצפנה מבוססת סריג |

 |
| 

| קריפטואנליזה |
| --- |
| ניתוח תדירויות • כוח גס • התקפת איזון זמן/זיכרון • תקיפת היפגשות באמצע • קריפטואנליזה ליניארית • קריפטואנליזה דיפרנציאלית • התקפת גלוי-ידוע • התקפת גלוי-נבחר • התקפת מוצפן-נבחר • פירוק לגורמים של מספר שלם • התקפת ערוץ צדדי • התקפת קורלציה • התקפת שיבוש • מודל אורקל אקראי • התקפת התנגשויות |

 |
| 

| בעיות מתמטיות ואלגוריתמים |
| --- |
| בעיית לוגריתם דיסקרטי • תחשיב אינדקסים • נפה ריבועית • אלגוריתם rho של פולרד • נפת שדה מספרים • אלגוריתם רו של פולרד ללוגריתמים • אלגוריתם פוליג-הלמן |

 |
| 

| פונקציות גיבוב קריפטוגרפיות |
| --- |
| SHA • MD5 • MD4 • SHA-1 • SHA-2 • SHA-3 • RIPEMD • Skein • BLAKE • Grøstl • SipHash |

 |
| 

| אימות וזיהוי |
| --- |
| אימות זהות • סיסמה • קוד אימות מסרים • Poly1305 • סיסמה חד-פעמית |

 |
| 

| נושאים נלווים |
| --- |
| מספר אקראי • מספר ראשוני • יתירות • מפתח שיחה • סטגנוגרפיה • הצפנה קוונטית • הצפנה פוסט-קוונטית • עקרון קרקהופס • אבטחת מידע • קריפטוגרפיה ויזואלית • אליס ובוב • מסיבת חתימה על מפתחות ציבוריים • שידור מוצפן • הצפנת דיסקים • הצפנת סף • חתימה דיגיטלית מבוססת פונקציית גיבוב • פונקציה זניחה • רשת פייסטל • רשת החלפה-תמורה • הלבנה • אימות מסרים • חתימה עיוורת • חישוב רב משתתפים בטוח |

 |