GCM

Galois/Counter Mode הוא מצב הפעלה של צופן בלוקים שפותח ב-2005 על ידי ג'ון ויגה מחברת Secure Software ודייוויד מקגרו מסיסקו, המשלב צופן סימטרי במצב מונה ופונקציית גיבוב אוניברסלית מעל שדה סופי מורחב, כדי לייצר הצפנה מאומתת עם מידע נלווה המסומנת בקיצור AEAD לפי פרדיגמה של "הצפנה ואז אימות". השיטה מבוססת על רעיון שהוכח כבטוח על ידי בלייר, קיליאן, רוגווי ואחרים ומסתמך גם על ביטחון הצופן הסימטרי שבבסיסו, בהנחה שהוא תמורה פסאודו-אקראית (צופן AES נראה כעונה להגדרה זו, אם כי לא קיימת הוכחה פורמלית). כמו כן GCM יעיל וקל להטמעה בחומרה ומאפשר ביצועים טובים גם בתוכנה, בעיקר אם מנצלים טבלאות אחזור (lookup table). האלגוריתם מצפין את המידע ומייצר טקסט מוצפן ותג אימות מהמידע המוצפן ומידע נלווה נוסף אם קיים, כאשר תג האימות מבטיח מעצם ההגדרה שלא ניתן יהיה לזייף טקסט מוצפן ותג מתאים ללא ידיעת מפתח ההצפנה הסודי המשותף, כך שפונקציית האימות של המקבל תחזיר 'אמת'.

GCM חופשי לשימוש ואינו מעוגן בפטנט או זכויות יוצרים. והוא אומץ על ידי המכון הלאומי לתקנים וטכנולוגיה של ממשלת ארצות הברית בתקן NIST SP800-38D להצפנה מאומתת ובתקן IEEE 802.1AE. הוצע ב- ונכלל בפרוטוקול SSL. הוא פופולרי בשל ביצועיו הטובים, תפוקתו מהמהירות הידועות כיום להצפנה מאומתת (בערך 3.7 cpb על מעבד אינטל 64 ביט).

==תיאור הערכים==
תרשים לדוגמה של הצפנה מאומתת עם מסר <math>P</math> המכיל שני בלוקים ומידע נלווה <math>A</math> המכיל בלוק אחד. הסמל <math>E_K</math> מייצג את צופן הבלוקים (לדוגמה [[AES) עם המפתח <math>K</math>. הסמל <math>\text{mult}_H</math> מייצג כפל פולינומים מעל <math>GF(2^{128})</math> (הסבר בהמשך), עם מפתח הגיבוב <math>H</math> אותו מייצרים על ידי הצפנה של מחרוזת אפסים. הסמל <math>\text{incr}</math> מייצג את פונקציית קידום המונה. פלט האלגוריתם הוא <math>C_1,C_2,T</math>.]]
====קלט====
*מפתח הצפנה <math>K</math> באורך המתאים לצופן הבלוקים שבשימוש (בדרך כלל 128 סיביות). מפתח ההצפנה צריך להיות משותף גם למקבל.
*וקטור אתחול <math>IV</math> שאינו סודי, בגודל הנע בין בית אחד ל-<math>2^{64}</math> בתים. הערך המומלץ לצורך ביצועים אופטימליים הוא 96 סיביות.
*טקסט מקור <math>P</math> בגודל שבין אפס בתים ל-<math>2^{39}-256</math>. מחרוזת ריקה מסומנת כאן "{}".
*דטה מאומתת נוספת המסומנת כאן <math>A</math>. זהו מידע גלוי נלווה, שאמור להיות מאומת אך לא מוצפן. בגודל של עד <math>2^{64}</math> בתים.

====פלט====
*טקסט מוצפן <math>C</math> שגודלו בדיוק כגודל <math>P</math>.
*תג אימות <math>T</math> שגודלו יכול להיות בין 64 ל-128 סיביות (בין שמונה לשישה עשר בתים). אורך התג מסומן כאן ב-<math>t</math>.

====פענוח ואימות====
אלגוריתם הפענוח המאומת מקבל את <math>K,IV,C,A,T</math> ומפיק את הטקסט המקורי <math>P</math> או סימן מיוחד "FAIL" המציין שהאימות נכשל, אם הייתה שגיאה. לפי הגדרת האלגוריתם, הפענוח המאומת יחזיר את <math>P</math> רק אם הערכים חושבו על ידי פונקציית ההצפנה המאומתת של GCM. במידה שאחד מהם שונה אפילו במעט, בסיכוי גבוה מאוד אלגוריתם הפענוח יחזיר הודעת שגיאה. כאשר אז המשמעות היא שאחד הערכים שגוי בגלל תקלה או בשל שינוי זדוני. המידע הנלווה <math>A</math> משמש כמידע תפעולי ועשוי להכיל כתובות IP, פורטים, מספרי גרסאות וכיוצא בזה. אילו בדרך כלל מהווים חלק מהכותר הנלווה למידע כדי לאפשר למערכת בצד השני לטפל בו בצורה נכונה, לכן אמור להיות במצב גלוי. הפרוטוקול מאפשר לאמת ולהבטיח את שלמות המידע הנלווה כדי להגן על סודיות המידע המוצפן מפני התקפת מוצפן-נבחר.

המטרה העיקרית של ה-<math>IV</math> שנקרא גם Nonce היא לספק ערך ייחודי וחד פעמי שנדרש בכל פעם שמפעילים את האלגוריתם עם מפתח <math>K</math> נתון. ה-<math>IV</math> אינו חייב להיות סודי ויכול להיות מספר אקראי או נומרטור כלשהו שצריך להיות ידוע גם לצד המקבל, המגבלה היחידה היא שלא יחזור על עצמו עם מפתח נתון. ב-GCM וקטור האתחול מאומת. אם <math>P</math> מכיל 0 בתים, ו-<math>A</math> מכיל בתים כלשהם, אזי למעשה מתקבל אימות של <math>A</math> בלבד. והיות ש-<math>A</math> נותר גלוי, במקרה זה GCM מתנהג כקוד אימות מסרים ללא הצפנה. זאת ללא שינוי באלגוריתם. לצורך ההבחנה מסמנים מקרה זה כ-GMAC. הערך <math>t</math> צריך להיות לפחות 64 כדי לקבל רמת ביטחון מינימלי של <math>2^{-64}</math>. לטענת המפתחים התקפה על GCM של חיפוש רנדומלי של תגים עד שנמצא זיוף, תצליח בהסתברות של <math>(B+1)2^{-t}</math> כאשר <math>B</math> הוא מספר הבלוקים שהוצפנו. לכן אפקטיבית חוזק התג הוא בסדר גודל של <math>t-\text{lg}B</math> סיביות. מסיבה זו לא מומלץ להצפין עם מפתח נתון יותר מ-<math>2^{68}</math> בתים.

==תיאור האלגוריתם==
באלגוריתם הבא <math>E</math> מייצג את צופן הבלוקים, פירוש <math>E(K,Y)</math> הוא הצפנה של <math>Y</math> עם המפתח <math>K</math>. הפונקציה <math>\text{len}(x)</math> מחזירה ערך בגודל 64 סיביות המייצג את מספר הסיביות של <math>x</math>. הביטוי <math>0^l</math> מתייחס למחרוזת של <math>l</math> אפסים. הביטוי <math>a\| b</math> מייצג שרשור, כלומר חיבור של <math>A</math> עם <math>B</math> למחרוזת ארוכה יותר המכילה את שניהם בזה אחר זה. הפונקציה <math>\text{MSB}_t(S)</math> מחזירה את <math>t</math> הסיביות המשמעותיות ביותר של <math>S</math>. הערכים <math>n,u</math> מייצגים את חלוקת המסר למקטעים לפי הנוסחה <math>(n-1)128+u</math>. כאשר <math>1\le u\le 128 </math> כך ש-<math>P</math> מורכב למעשה ממערך של <math>n-1</math> בלוקים בגודל 128 סיביות פלוס בלוק אחד בגודל <math>u</math> סיביות המרופד באפסים לפי הצורך כדי להשלימו לגודל בלוק מלא. למעשה מתקבל <math>P_1,P_2,...,P_{n-1},P_n^*</math> (הכוכבית מציינת שאורכו של הבלוק האחרון יכול להיות קטן מ-128). וכן לגבי <math>C</math>. והמידע הנלווה <math>A</math> הוא <math>A_1,A_2,...,A_{m-1},A_m^*</math>. כאשר סך כל סיביות <math>A</math> הוא <math>(m-1)128+v</math>. ו-<math>1\le v\le 128</math>. הפונקציה <math>\text{incr}(Y)</math> מייצגת קידום ערכו של <math>Y</math> באחד מודולו <math>2^{32}</math>. למעשה <math>Y</math> יכול להיות גדול מ-32 סיביות אך המונה נשאר בשל הצמצום המודולרי בגודל 32 סיביות. הסימן <math>\oplus</math> מייצג XOR והפונקציה GHASH מוגדרת להלן.

====מהלכי ההצפנה====
<div class="mw-content-ltr">
::#<math>H=E_K(0^{128})</math>
::#<math>Y_0=\begin{cases} IV \ \| \ 0^{31}1, & \text{if } \text{len}(IV)=96 \\ \text{GHASH}(H,\{\},IV), & \text{otherwise} \end{cases}</math>
::#<math>Y_i=\text{incr}(Y_{i-1})\text{ for }i=1,...,n-1</math>
::#<math>C_i=P_i\oplus E_K(Y_i)\text{ for }i=1,...,n-1</math>
::#<math>C_n^*=P_n^*\oplus \text{MSB}_u(E_K(Y_n))</math>
::#<math>T=\text{MSB}_t(\text{GHASH}(H,A,C)\oplus E_K(Y_0))</math>
</div>
במילים, תחילה מצפינים מחרוזת של 128 אפסים עם המפתח הסודי <math>K</math>, לאחר מכן מכינים את ערכו ההתחלתי של המונה <math>Y</math> לאחר מכן מבצעים איטרציה ומכינים את כל ערכי המונה הדרושים: מחברים את המונים עם בלוקי הטקסט הקריא אחד אחרי השני באמצעות XOR להפקת הטקסט המוצפן ולאימות משתמשים ב-GHASH עם מפתח האימות והמידע הנלווה ומחברים ב-XOR עם הצפנת צופן הבלוקים עם המפתח <math>H</math> (שהוא טקסט מוצפן של וקטור האתחול שהוצפן עם המפתח <math>K</math>.

====הפונקציה GHASH====
פונקציה רקורסיבית המגדירה את ערכי <math>X_i</math> החל מ-<math>i=0</math> עד <math>i=m+n+1</math> כדלהלן:
<div class="mw-content-ltr">
:<math>X_i= \begin{cases} 0, & \text{for }i=0 \\ (X_{i-1}\oplus A_i)\cdot H, & \text{for }i=1,...,m-1 \\ (X_{m-1}\oplus (A_m^* \ \| \ 0^{128-v}))\cdot H, & \text{for }i=m \\ (X_{i-1}\oplus (C_{i-m})\cdot H, & \text{for }i=m+1,...,m+n-1 \\ (X_{m+n-1}\oplus (C_n^* \ \| \ 0^{128-u}))\cdot H, & \text{for }i=m+n \\ (X_{m+n}\oplus (\text{len}(A) \ \| \ \text{len}(C)))\cdot H, & \text{for }i=m+n+1 \\ \end{cases}</math>
</div>

====מהלכי הפענוח====
<div class="mw-content-ltr">
::#<math>H=E_K(0^{128})</math>
::#<math>Y_0=\begin{cases} IV \ \| \ 0^{31}1, & \text{if } \text{len}(IV)=96 \\ \text{GHASH}(H,\{\},IV), & \text{otherwise} \end{cases}</math>
::#<math>T'=\text{MSB}_t(\text{GHASH}(H,A,C)\oplus E_K(Y_0))</math>
::#<math>Y_i=\text{incr}(Y_{i-1})\text{ for }i=1,...,n</math>
::#<math>P_i=C_i\oplus E_K(Y_i)\text{ for }i=1,...,n</math>
::#<math>P_n^*=C_n^*\oplus \text{MSB}_u(E_K(Y_n))</math>
</div>
תג האימות <math>T'</math> מושווה לתג המקורי <math>T</math> שהגיע יחד עם <math>C</math>. אם הם שווים מוחזר <math>P</math> אם לא, מוחזר "FAIL". שים לב שכדי למנוע התקפת תזמון, התהליך מתנהל באופן זהה גם במקרה של שגיאה כלומר במקרה של כישלון FAIL יוחזר רק לאחר שורה 6. אף על פי שאפשר לדעת אם חל שינוי בחלק מהערכים שהתקבלו כבר בשורה 3.

==כפל פולינומים מעל השדה <math>GF(2^{128})</math>==
בפונקציה GHASH מבוצע כפל מודולרי בשדה הבינארי <math>\mathbb{F}_{2^{128}}</math> מודולו <math>2^{128}</math>. כלומר רואים במחרוזות הסיביות 'כמקדמים בינאריים' של פולינומים ממעלה נמוכה מ-128 לפי סדר בתים גדול (כלומר הסיבית הכי המשמעותית מייצגת את המקדם הראשון). לצורך הצמצום המודולרי משתמשים בפולינום פרימיטיבי קבוע <math>f(\alpha)=\alpha^{128}+\alpha^7+\alpha^2+\alpha+1</math> המיוצג על ידי המחרוזת <math>R=11100001 \ \| \ 0^{120}</math> (כלומר הבית הראשון מכיל את 11100001 (0xE1) והיתר אפסים, בסך הכול 128 סיביות או 16 בתים).

בפונקציה מתבצע הכפל של הקבוע <math>H</math> (שהוא תוצאת הצפנה של מחרוזת אפסים) במשתנה <math>X</math> הדרך הארוכה לחישוב <math>X\cdot H</math> אינה יעילה, אפשר לפשט את התהליך על ידי רקורסיה של הכפלות בפולינום <math>\alpha</math> המיוצג על ידי האלמנט <math>P</math> המקביל למחרוזת הבינארית '10' (או בבסיס הקסדצימלי 0x02). פעולה זו שוות ערך לפעולת Shift left, כלומר הזזה של כל הסיביות שמאלה (למעלה) פוזיציה אחת, הסיבית המשמעותית ביותר נפלטת והסיבית הראשונה מתאפסת, הפעולה Shift מובנית בכל המעבדים והיא יעילה. אם הסיבית המשמעותית ביותר של <math>X</math> (לפני ההזזה) המיוצגת על ידי <math>X_{127}</math> היא אפס, מתקבל למעשה פולינום ממעלה 127, אחרת התרחשה גלישה ולכן לפי כללי החשבון המודולרי יש צורך לחלק את התוצאה בפולינום הפרימיטיבי <math>f(\alpha)</math> ולקחת את השארית. כלומר למצוא <math>q</math> ו-<math>r</math> המקיימים <math>\alpha^{128}+\alpha=q\cdot f+r</math>. קל לפתור את המשוואה עבור המקרה <math>q=1</math> כי אז מתקבל <math>r=\alpha^{128}+\alpha-f</math>. יוצא שהצמצום המודולרי מקביל למעשה לפעולת חיסור אחת במקדמים הנמוכים של <math>f</math>. בשדה בינארי פעולת חיבור מתבצעת על כל המקדמים בנפרד מודולו 2 שהיא מקבילה למעשה לפעולת XOR. היות ש-XOR הופכי של עצמו חיסור זהה לחיבור.

בסיכומו של דבר הכפל ב-<math>\alpha</math> דורש רק הזזת כל סיביות המחרוזת פוזיציה אחת ופעולת XOR מותנית אחת עם הקבוע לעיל. שהן כידוע פעולות מהירות וזולות במונחי מחשוב. מכאן הדרך לביצוע כל כפל ביעילות רבה ברקורסיה. כדי לחשב את <math>Y\cdot X</math> מייצגים את <math>Y</math> כחזקות של האלמנט <math>P</math>, מבצעים רקורסיה <math>X,X\cdot P,X\cdot P^2,...</math> כלומר בכל שלב מכפילים את <math>X</math> ב-<math>P</math> בשיטה המתוארת ואם <math>Y_i=1</math> מבצעים חיבור אחד נוסף ב-XOR (מלבד החיסור המותנה בכפל ב-<math>P</math>), התוצאה היא ב-<math>Z</math> כדלהלן:
<div class="mw-content-ltr">
:<math>Z=0,V=X</math>
:<math>\text{for }i=0\text{ to }127\text{ do:}</math>
::<math>\text{if }Y_i=1\text{ then: } Z=Z\oplus V</math>
::<math>V=V\cdot P</math>
:<math>\text{Return }Z</math>
</div>
מספר הפעמים שיש להפעיל את אלגוריתם הכפל בהצפנה אחת של טקסט בגודל <math>p</math> סיביות הוא <math>\left \lceil p/128 \right \rceil +1</math>. וכן אם יש מידע נלווה בגודל <math>q</math> סיביות יש להוסיף <math>\left \lceil q/128 \right \rceil +1</math> פעולות כפל. יתרה מזו, אם הזיכרון זמין, אפשר להאיץ את פעולת הכפל על ידי הכנה מוקדמת של טבלאות כפל. כלומר כדי לחשב את <math>X\cdot H</math> אפשר להכין טבלה של תת-קבוצה של חזקות של <math>H</math>. אם מחלקים את 128 הסיביות של <math>H</math> ל-16 בתים, ומכינים 16 טבלאות <math>M_0,...,M_{15}</math> של 256 ערכים כל אחת, פעולת הכפל של <math>X</math> כלשהו יכולה להיות:
:<math>Z=M_0[x_0]\oplus M_1[x_1]\oplus \cdots \oplus M_{15}[x_{15}]</math>.
הערך <math>X_i</math> מתייחס לבית ה-<math>i</math> של <math>X</math>. הרעיון הוא שאם מבודדים שמונה סיביות של <math>X</math> כלשהו פעולת הכפל ב-<math>H</math> היא תוצאה אחת מתוך <math>2^8</math> תוצאות אפשריות, כלומר 256 אלמנטים. אם מכפילים ב-16 מתקבל למעשה כל האפשרויות כאשר סך כל הזיכרון המנוצל הוא 65,536 בתים. ויקטור שופ הציע רעיון לצמצם את דרישות הזיכרון במחיר של חישוב ארוך יותר. אפשר להיפטר מכל הטבלאות <math>M_i</math> למעט <math>M_0</math> ולבצע את הכפל כדלהלן:
:<math>H\cdot X=H\cdot \bigoplus_{i=0}^{15} x_i\cdot P^{8i} = \bigoplus_{i=0}^{15} (x_i\cdot H)\cdot P^{8i}</math>
כלומר אפשר לבצע את הכפל ב-<math>P^8</math> רקורסיבית יחד עם פעולות XOR. וכן להיעזר בטבלה <math>M_0</math> כדי לחשב את <math>x_i\cdot H</math>. אולם תהיה בעיה של עם <math>P^{128}</math> כי הוא חורג מגודל 16 בתים. אפשר להוסיף טבלה <math>R</math> שתכלול את כפולות <math>x</math> ב-<math>P^{128}</math>. בשיטת שופ אפשר לצמצם את דרישות הזיכרון של שתי הטבלאות <math>M_0</math> ו-<math>R</math> לסך הכול 256 ועוד 64 בתים במחיר של מעט עבודה נוספת. להלן תיאור אלגוריתם שופ:

<div class="mw-content-ltr">
:<math>Z=0</math>
:<math>\text{for }i=15 \text{ down to }1\text{ do:}</math>
::<math>Z=Z\oplus M_0[X_i]</math>
::<math>A=X_{15}</math>
::<math>\text{for }j=15\text{ down to }1\text{ do:}</math>
:::<math>Z_j=Z_{j-1}</math>
::<math>Z=Z\oplus R[A]</math>
:<math>Z=Z\oplus M_0[X_0]</math>
:<math>\text{Return }Z</math>
</div>

האלגוריתם להכנת הטבלה <math>M_0</math> הוא:

<div class="mw-content-ltr">
:<math>M_{128}=H,i=64</math>
:<math>\text{While }i>0\text{ do }</math>
::<math>M_i=M_{2i}\cdot P,i=\left\lfloor i/2\right\rfloor</math>
:<math>i=2</math>
:<math>\text{While }i<128\text{ do }</math>
::<math>\text{For }j=1\text{ to }i-1\text{ do: }M_{i+j}=M_i\oplus M_j</math>
::<math>i=2i</math>
:<math>M_0=0^{128}</math>
</div>

באותה דרך אפשר להכין את יתר הטבלאות <math>M_1,...,M_{15}</math>.

==ביטחון ויעילות==
GCM בנוי לפי פרדיגמה של הצפנה מאומתת שנקראת "הצפנה ואז אימות" (encrypt-then-authenticate) שידועה בביטחון שהיא מספקת, בתנאי שהמרכיבים הבסיסיים כמו הצופן הסימטרי ופונקציית הגיבוב בטוחים. ההעדפה של מצב מונה נובעת מתכונת המקביליות ומהפשטות שלו. וניצול כפל פולינומים מעל השדה המורחב <math>GF(2^{128})</math> נובע גם בשל תכונת האקראיות המוכחת ובשל היעילות במימוש במיוחד בחומרה. פחות מעגלים ופחות עיכובים בצינור עיבוד נתונים. הפולינום של השדה נבחר באופן שיכיל משקל נמוך (מספר סיביות אחד נמוך) והוא נלקח מטבלה של גדיאל סרוסי מהטכניון. לצורך האלגוריתם נדרש רק מפתח הצפנה יחיד, בעוד שמפתח פונקציית האימות נגזר ממנו. השימוש בכפל פולינומים מעל שדה בינארי מורחב, הוכח כבטוח נגד התקפת גלוי-נבחר על ידי בלייר, קיליאן, רוגווי ואחרים. השימוש בפונקציית גיבוב 'אוניברסלית' להבטחת שלמות ואימות כמו בקוד אימות מסרים הוכח כבטוח על ידי ווגמן וקרטר. מצב מונה שהועלה לראשונה על ידי דיפי והלמן ב-1979 הוכח על ידם כיעיל ובטוח. לפי הצהרת המפתחים תפוקת האלגוריתם עם זיכרון של 256 בתים עומדת על כ-90 מחזורי שעון לבית בממוצע. וכן הסיכויים להתקפה מוצלחת כנגד מנגנון האימות הם בהסתברות של <math>2^{-t}</math>.

ניילס פרגוסון (ממפתחי אלגוריתם Twofish) גילה שתי חולשות במנגנון האימות של GCM כאשר משתמשים בתג אימות קצר כמו 32 או 8 סיביות, בנוסף להערות טכניות לגבי התכנון של GCM. הבעיה הראשונה שהעלה מראה שאפשר להעלות את הסיכויים לזיוף מוצלח לכדי חצי ממה שצפוי, לדוגמה עבור תג אימות בגודל 32 סיביות הסיכויים הם <math>2^{-16}</math>, שזה גבוה במידה ניכרת ממה שהצהירו המפתחים. הסיבה לבעיה אינה GHASH עצמה כיוון שהפונקציה מוכחת כחד כיוונית והתנגשויות הן בהסתברות של <math>2^{-(128-k)}</math> עבור <math>2^k</math> בלוקים. הסיבה לנקודת התורפה נעוצה בעובדה שתוצאת GHASH מוצפנת על ידי המפתח באמצעות XOR שכידוע אינו מגן מפני מניפולציה של סיביות הפלט (כלומר קלט עם סיבית שגויה אחת ישפיע רק על הסיבית המקבילה בפלט, זוהי פרצה שמאפשרת התקפה כאשר ידוע איזו סיבית שגויה). אבל הבעיה היותר חמורה היא שבעקבות זיוף מוצלח אחד ניתן להגביר את הסיכויים לחשיפת סיביות אחרות של מפתח האימות <math>H</math> עד כדי חשיפת המפתח כולו אחרי מספר ניסיונות די קצר. ההמלצה שלו היא להשתמש בתג אימות באורך 128 סיביות ולא פחות או במנגנון אימות אחר. אם למשל משנים את GCM כך שלפני XOR עם המפתח מצפינים את התוצאה באמצעות צופן הבלוקים נראה שהבעיה תיפתר על חשבון יעילות.

כמו כן מעלה נילס פרגוסון כמה מגבלות ראויות לציון בתכנון GCM. העובדה שאורך המסר המאומת הוגבל ל-<math>2^{36}-64</math> שזה יחסית קצר וכן העובדה שהאלגוריתם אינו מגביל את אורך המסר לגבולות בתים מה שעלול ליצור בעיות תאימות וכן העובדה שבמצב אופטימלי נדרשות טבלאות גדולות כדי להגיע לביצועים גבוהים, מה שלטענתו אינו מעשי.
===יתרונות===
*מצב מונה נחשב בעיקרון למצב הפעלה מהיר, בטוח ויעיל. השימוש בפעולות אלגבריות פשוטות בשדה <math>GF(2^{128})</math> ניתן למימוש יעיל ומאפשר ביצועים טובים הן בתוכנה והן בחומרה (להלן שיטות יישום מהירות ואלגוריתמים).
*אפשר להשתמש ב-GCM גם כקוד אימות מסרים עצמאי, כאשר אין צורך בהצפנה, ללא מאמץ מיוחד.
*במקרה שבוצע שינוי במסר לאחר שתג האימות עבורו הוכן, אפשר לחשב את התג מחדש במאמץ שהוא פרופורציונלי למספר הסיביות ששונו.
*האלגוריתם מקבל וקטור אתחול באורך שרירותי. כך שאפשר לנצל קטע נתונים כלשהו גם אם גודלו עולה על גודל הבלוק שהצופן מקבל.

==ראו גם==
* מצב הפעלה של צופן בלוקים
* CCM
* OCB
* EAX

==לקריאה נוספת==
*McGrew, David A.; Viega, John (2005). "The Galois/Counter Mode of Operation (GCM)". p. 5. Retrieved 20 July 2013. Note that there is a typo in the formulas in the article.
==הערות שוליים==

קטגוריה:קריפטוגרפיה