توضح هذه المقالة تفاصيل خوارزمية تشفير البلوك المعرفة في GOST R 34.12-2015 باسم Grasshopper. ما الذي تستند إليه ، وما هي رياضيات خوارزميات تشفير البلوك ، وكيف يتم تنفيذ هذه الخوارزمية في جافا.
مَن ، وكيف ، ومتى ، ولماذا طورت هذه الخوارزمية التي ستظل خارج نطاق المقالة ، لأننا في هذه الحالة نحرص قليلًا ، باستثناء:
جندب = كوزنيتسوف ، نيتشيف أند كومباني.

نظرًا لأن التشفير يعتمد أساسًا على الرياضيات ، بحيث لا يتسبب التفسير الإضافي في الكثير من الأسئلة ، يجب أولاً تحليل المفاهيم الأساسية والوظائف الرياضية التي بنيت عليها هذه الخوارزمية.
الحقول جالوا
حساب حقول جالوا هو حساب متعدد الحدود ، أي أن كل عنصر من عناصر هذا الحقل متعدد الحدود. نتيجة أي عملية هي أيضا عنصر في هذا المجال. يتكون حقل غالوا معين من مجموعة ثابتة من الأرقام. وتسمى خاصية الحقل عدد أولي p. ترتيب الحقول ، أي كمية عناصرها هي درجة طبيعية معينة من الخصائص
pm ، حيث m ϵ N. بالنسبة إلى m = 1 ، يُسمى الحقل بسيط. في الحالات التي تكون فيها m> 1 ، لتشكيل مجال ما ، هناك حاجة أيضًا إلى توليد متعدد الحدود من الدرجة m ؛ ويُسمى هذا الحقل ممتدًا.
Gf(pm) - تعيين حقل جالوا. كثير الحدود المولدة غير قابلة للاختزال ، وهذا بسيط ، (بالقياس مع الأعداد الأولية ، يكون قابلاً للقسمة على 1 وفي حد ذاته دون الباقي). نظرًا لأن العمل مع أي معلومات يعمل مع وحدات البايت ، والبايت هو 8 بت ، خذ كحقل
Gf(28) وتوليد متعدد الحدود:
x8+x7+x6+x+1.
ومع ذلك ، بادئ ذي بدء ، سنقوم بتحليل العمليات الأساسية في مجال أبسط
Gf(23) مع توليد متعدد الحدود
f(x)=x3+x+1 .
عملية إضافة
إن أبسطها هي عملية الإضافة ، والتي في حقل جالوا هي عبارة عن معامل إضافة بسيط في اتجاه حركة البت 2 (R).
أود على الفور لفت الانتباه إلى حقيقة أن علامة "+" هنا وهنا تشير إلى تشغيل XOR bitwise ، وليس الإضافة في الشكل المعتاد.
جدول الحقيقة لوظيفة HOR

مثال:
5+3=101+011=1102=610في كثير الحدود ، ستبدو هذه العملية
(x2+1)+(x+1)=x2+x=1102=610
عملية الضرب
لتنفيذ عملية الضرب ، من الضروري تحويل الأرقام إلى شكل متعدد الحدود:
5=1012=1∗x2+0∗x1+1∗x0=x2+1
كما ترون ، الرقم في كثير الحدود هو متعدد الحدود الذي معاملاته هي قيم الأرقام في التمثيل الثنائي للرقم.
اضرب رقمين في كثير الحدود:
5∗7=(x2+1)∗(x2+x+1)=x4+x3+x2+x2+x+1=
=x4+x3+x+1=110112=2710
نتيجة الضرب 27 ليست في الحقل المستخدم.
Gf(23) (يتكون من أرقام من 0 إلى 7 ، كما ذكر أعلاه). لمكافحة هذه المشكلة ، من الضروري استخدام متعدد الحدود توليد.
من المفترض أيضًا أن x يرضي المعادلة
f(x)=x3+x+1=0 ثم

لنجعل جدول الضرب:

من الأهمية بمكان وجود جدول درجات عناصر حقل جالوا. كما يتم رفع القوة في كثير الحدود ، على غرار الضرب.
مثال:
52=(x2+1)2=x4+x2+x2+1=x4+x2+x+x2+x+1=
=x(x3+x+1)+x2+x+1=x2+x+1=1112=710
وبالتالي ، نقوم بتجميع جدول الدرجات:

جدول الدرجة هو دوري: الدرجة السابعة تقابل الصفر ، وبالتالي فإن الثامن يتوافق مع الأول ، إلخ. يمكنك التحقق من هذا إذا كنت ترغب في ذلك.
في حقول غالوا ، هناك مفهوم للمصطلح البدائي - عنصر في حقل تحتوي درجته على جميع العناصر غير الصفرية للحقل. يمكن ملاحظة أن جميع العناصر تتوافق مع هذا الشرط (جيدًا ، باستثناء 1 ، بالطبع). ومع ذلك ، هذا ليس هو الحال دائما.
بالنسبة للحقول التي ندرسها ، أي ، مع الخاصية 2 ، اختر دائمًا 2. كعضو بدائي ، نظرًا لخصائصه ، يمكن التعبير عن أي عنصر في الحقل من حيث درجة العضو البدائي.

مثال:
5=26.7=25باستخدام هذه الخاصية ، ومع مراعاة الدورية لجدول الدرجات ، سنحاول ضرب الأرقام مرة أخرى:
5∗7=26∗25=2(6+5)=2(11mod7)=24=6
تزامنت النتيجة مع ما حسبنا في وقت سابق.
الآن دعونا نفعل القسم:
6/5=24/26=2(4−6)=2((−2)mod7)=25=7
النتيجة التي تم الحصول عليها صحيحة أيضا.
حسنًا ، من أجل الاكتمال ، دعونا ننظر إلى رفع مستوى القوة:
52=(26)2=2(6∗2)=2(12mod7)=25=7
مثل هذا النهج في الضرب والقسمة هو أبسط بكثير من العمليات الحقيقية باستخدام كثير الحدود ، وليس هناك حاجة لتخزين جدول الضرب الكبير ، ولكن مجرد صف من درجات عضو الحقل البدائي.
عاد الآن إلى مجالنا
Gf(28)عنصر الصفر في الحقل واحد ، الأول هو اثنان ، كل عنصر لاحق من العنصر 2 إلى 254 يتم حسابه باعتباره العنصر السابق ، مضروبًا في 2 ، وإذا كان العنصر خارج الحقل ، فستكون قيمته أكبر من
(28−1) ثم يتم XOR مع الرقم
19510دولا ، هذا الرقم يمثل كثير الحدود غير القابلة للاختزال من الحقل
x8+x7+x6+x+1=28+27++26+2+1=451 ، نأتي هذا الرقم إلى الميدان

. والعنصر 255 هو مرة أخرى 1. لذلك لدينا حقل يحتوي على 256 عنصرًا ، أي مجموعة كاملة من وحدات البايت ، وقمنا بتحليل العمليات الأساسية التي يتم تنفيذها في هذا الحقل.

جدول صلاحيات اثنين لهذا المجال
Gf(28)سبب الحاجة - يتم إجراء جزء من العمليات الحسابية في خوارزمية Grasshopper في حقل Galois ، وتكون نتائج العمليات الحسابية بناءً على ذلك عناصر في هذا الحقل.
شبكة فيستل
Feistel Network هي طريقة تشفير بلوك طورتها شركة Horst Feistel في شركة IBM في عام 1971. شبكة Feistel اليوم هي أساس عدد كبير من بروتوكولات التشفير.
تعمل شبكة Feistel مع كتل نصية واضحة:
- يتم تقسيم الكتلة إلى قسمين متساويين - اليسار L واليمين R.
- يتم تغيير الكتلة الفرعية اليسرى L بواسطة الدالة f باستخدام المفتاح K: X = f (L، K). كدالة ، يمكن أن يكون هناك أي تحول.
- تتم إضافة الكتلة الفرعية الناتجة X معامل 2 مع subblock الأيمن R ، الذي لم يتغير: X = X + R.
- الأجزاء الناتجة متبادلة ولصقها.
هذا التسلسل من الإجراءات يسمى خلية Feistel.
الشكل 1. خلية Feistelتتكون شبكة Feistel من عدة خلايا. تذهب القوالب الفرعية التي تم الحصول عليها عند إخراج الخلية الأولى إلى إدخال الخلية الثانية ، وتذهب القوالب الفرعية الناتجة من الخلية الثانية إلى إدخال الخلية الثالثة وما إلى ذلك.
خوارزمية التشفير
الآن أصبحنا على دراية بالعمليات المستخدمة ويمكننا الانتقال إلى الموضوع الرئيسي - وهي خوارزمية تشفير Grasshopper.
أساس الخوارزمية هو ما يسمى بشبكة SP - شبكة تبديل الإحلال. يتلقى التشفير القائم على شبكة SP كتلة ومفتاحًا عند الإدخال ويقوم بالعديد من جولات التناوب التي تتكون من مراحل الاستبدال ومراحل التقليب. يقوم Grasshopper بتسع جولات كاملة ، تشمل كل منها ثلاث عمليات متتالية:
- تشغيل تطبيق مفتاح مستدير أو XOR bitwise للمفتاح وكتلة بيانات الإدخال ؛
- تحويل غير خطي ، وهو بديل بسيط للبايت بأخرى وفقاً للجدول ؛
- التحول الخطي. يتم ضرب كل بايت من الكتلة في حقل غالوا بواحد من معاملات السلسلة (148 ، 32 ، 133 ، 16 ، 194 ، 192 ، 1 ، 251 ، 1 ، 192 ، 194 ، 16 ، 133 ، 32 ، 148 ، 1) اعتمادًا على الترتيبي أرقام البايت (يتم تقديم سلسلة للأرقام التسلسلية من 15 إلى 0 ، كما هو موضح في الشكل). تتم إضافة وحدات البايت معًا للمعيار 2 ، ويتم تحويل جميع وحدات البايت 16 للكتلة باتجاه الترتيب المنخفض ، ويتم كتابة الرقم الناتج بدلاً من بايت القراءة.

الجولة العاشرة الأخيرة ليست كاملة ، فهي تشمل فقط عملية XOR الأولى.
Grasshopper عبارة عن خوارزمية كتلة ، وهي تعمل مع كتل بيانات يبلغ طولها 128 بت أو 16 بايت. طول المفتاح هو 256 بت (32 بايت).
الشكل 2. مخطط التشفير وفك التشفير من كتلة البياناتيوضح الرسم البياني تسلسل العمليات ، حيث S عبارة عن تحويل غير خطي ، L عبارة عن تحويل خطي ، Ki هي مفاتيح مستديرة. السؤال الذي يطرح نفسه على الفور - من أين تأتي المفاتيح المستديرة.
تشكيل مفتاح الجولة
يتم الحصول على مفاتيح تكرارية (أو مستديرة) من خلال تحويلات معينة تستند إلى مفتاح رئيسي ، يبلغ طوله ، كما نعلم بالفعل ، 256 بت. تبدأ هذه العملية بتقسيم المفتاح الرئيسي إلى النصف ، بحيث يتم الحصول على الزوج الأول من المفاتيح المستديرة. تُستخدم ثماني تكرارات من شبكة Feistel لإنشاء كل زوج من المفاتيح الدائرية اللاحقة ، ويتم استخدام ثابت في كل تكرار ، ويتم حسابه عن طريق تطبيق تحويل خطي للخوارزمية على قيمة رقم التكرار.
مخطط الحصول على مفاتيح تكرارية (مستديرة)إذا تذكرنا بالشكل 1 ، فإن الكتلة الفرعية اليسرى L هي النصف الأيسر من المفتاح الأصلي ، وتكون الكتلة الفرعية اليمنى R هي النصف الأيمن من المفتاح الأصلي ، K هي Ci الثابتة ، والوظيفة f هي تسلسل العمليات R XOR Ci ، والتحول غير الخطي ، والتحول الخطي.
يتم الحصول على ثوابت التكرار Ci باستخدام التحويل L لرقم تسلسل التكرار.
لذلك ، من أجل تشفير كتلة من النص ، نحتاج أولاً إلى حساب 32 ثوابت متكررة ، ثم حساب 10 مفاتيح دائرية بناءً على المفتاح ، ثم إجراء تسلسل العمليات الموضح في الشكل 2.
لنبدأ بحساب الثوابت:
أول const
C1=110=000000012=0116 ومع ذلك ، يتم تنفيذ جميع التحويلات في خوارزمية لدينا مع كتل من 16 بايت ، وبالتالي فمن الضروري أن تكملة ثابت مع طول الكتلة ، أي إضافة 15 صفر بايت إلى اليمين ، نحصل على

اضربها بسلسلة (1 ، 148 ، 32 ، 133 ، 16 ، 194 ، 192 ، 1 ، 251 ، 1 ، 192 ، 194 ، 16 ، 133 ، 32 ، 148) على النحو التالي:
a15=a15∗148+a14∗32+a13∗133+a12∗16+
+a11∗194+a10∗192+a9∗1+a8∗251+a7∗1+a6∗192+
+a5∗194+a4∗16+a3∗133+a2∗32+a1∗148+a0∗1
(يتم إعطاء هذه المساواة في عمليات حقول جالوا)
نظرًا لأن كل شيء ما عدا صفر بايت يساوي 0 ، وضرب بايت صفر في 1 ، نحصل على 1 ونكتبه بالترتيب العالي للرقم ، ونحول كل البايتات إلى الترتيب المنخفض ، نحصل على:

كرر نفس العمليات. هذه المرة
a15=1دولا ، جميع البايتات الأخرى هي 0 ، لذلك ، يبقى الأول فقط من الشروط
a15∗148=1∗148=14810=9416 حصلنا على:

نقوم بالتكرار الثالث ، فيما يلي مصطلحين غير صفريين:
a15∗148+a14∗32=148∗148+1∗32=
=10010100∗10010100+00000001∗00100000=
=(x7+x4+x2)∗(x7+x4+x2)+1∗x5=x14+x8+x4+س5=
=x6(x8+x7+x6+x+1)+x13+x12+x7+x6+x8+x4+x5=
=x5(x8+x7+x6+x+1)+x11+x5+x7+x8+x4+x5=
=x3(x8+x7+x6+x+1)+x10+x9+x3+x8+x7=
=x2(x8+x7+x6+x+1)+x2+x7=x7+x2=13210
13210=8416
وفقًا لجدول الدرجات ، يمكن حلها بسهولة أكبر:


علاوة على ذلك ، كل شيء هو نفسه بالضبط ، فقط 16 تكرار لكل ثابت












والثابت النهائي:

الثوابت الأخرى:








C10=0AC1615EA018B5173AA2953EF2DADE2A
C11=0B55E583B0A5924A82D8DD5280AC7C44
C12=0C3FFFD5C010671A2C7DE6951D2D948D
C13=0DAB7B08D0AD40479407AEF96F5B36E3
C14=0ED434ACE0A929A09F89764DF9C11351
C15=0F40B071F0140EFD27F33E218BB7B13F
C16=1054974EC3813599D1AC0A0F2C6CB22F
C17=11C01393D33C12C469D642635E1A1041
C18=12BF5C37E3387B2362589AD7C88035F3
C19=132BD8EAF3855C7EDA22D2BBBAF6979D
C20=1441C2BC8330A92E7487E97C27777F54
C21=15D54661938D8E73CCFDA1105501DD3A
C22=16AA09C5A389E794C77379A4C39BF888
C23=173E8D18B334C0C97F0931C8B1ED5AE6
C24=187E3D694320CE3458FA0FE93A5AEBD9
C25=19EAB9B4539DE969E0804785482C49B7
C26=1A95F6106399808EEB0E9F31DEB66C05
C27=1B0172CD7324A7D35374D75DACC0CE6B
C28=1C6B689B03915283FDD1EC9A314126A2
C29=1DFFEC46132C75DE45ABA4F6433784CC
C30=1E80A3E223281C394E257C42D5ADA17E
C31=1F14273F33953B64F65F342EA7DB0310
C32=20A8ED9C45C16AF1619B141E58D8A75E
سنقوم الآن بحساب المفاتيح المستديرة وفقًا للمخطط الموضح أعلاه ، خذ مفتاح التشفير:

EFCDAB89674523011032547698BADCFE
ثم


K1 ستكون الكتلة الفرعية اليسرى لشبكة Feistel و
K2دولا - صحيح.
دعونا نفعل العملية
K1+C1البايت الأول
K1 يساوي
7716=011101112البايت الأول
C1 يساوي
0116=000000012011101112+000000012=011101102=7616
يتم تحويل البايتات المتبقية بنفس الطريقة ، نتيجة لذلك

:
X(K1،C1)=76F2D199239F365D479495A0C9DC3BE6
بعد ذلك ، نقوم بإجراء تحول غير خطي
S(X(K1،C1)) . يتم تنفيذها وفقا للجدول:
جدول تحويل غير خطييتم استبدال الرقم 0 ب 252 ، 1 ب 238 ، 17 ب 119 ، إلخ.
7616=11810
S(118)=13810=8A16
S(X(K1،C1))=8A741BE85A4A8FB7AB7A94A737CA9809
الآن إجراء التحول الخطي
L(S(X(K1،C1))) ، تم النظر فيه بالتفصيل عند حساب الثوابت التكرارية ، لذلك نحن هنا نعطي النتيجة النهائية فقط:
L(S(X(K1،C1)))=A644615E1D0757926A5DB79D9940093D
وفقًا لخطة خلية Feistel ، نقوم بإجراء XOR مع الكتلة الفرعية اليمنى ، على سبيل المثال ، مع
K2دولا :
X(L(S(X(K1،C1)))،K2)=4989CAD77A4274937A6FE3EB01FAD5C3
والنتيجة التي تم الحصول عليها في إخراج أول خلية فيستل:
EFCDAB89674523011032547698BADCFE4989CAD77A4274937A6FE3EB01FAD5C3
هذه القيمة إلى النصف وتذهب إلى إدخال خلية Feistel الثانية ، حيث يتم استخدام الثابت الثاني بالفعل

. بعد المرور عبر ثماني خلايا ، نحصل على المفتاحين التاليين
K3دولا و
K4دولا . سنقوم بإجراء ثماني تكرارات لشبكة Feistel معهم ، والحصول على زوج المفاتيح التالي ، وهكذا. ثماني تكرارات لكل زوج رئيسي ، نظرًا لأن لدينا في البداية الزوج الأول ، يتم تنفيذ 32 تكرارًا في المجموع ، لكل منها ثابتها الخاص.
المفاتيح المتبقية:

K4=04FD9F0AC4ADEB1568ECCFE9D853453D




K9=17E5B6CD732FF3A52331C77853E244BB
K10=43404A8EA8BA5D755BF4BC1674DDE972
كتلة التشفير
لقد قمنا بحساب جميع المفاتيح ، وأخيراً يمكننا الآن الانتقال مباشرة إلى تشفير كتلة النص وإذا كنت تقرأ بعناية كل ما كتب أعلاه ، فلن يكون تشفير النص أمرًا صعبًا ، حيث أن جميع العمليات المستخدمة في هذه العملية وتسلسلها قد تم فحصها بالتفصيل.
خذ كتلة النص العادي:

تنفيذ تسلسل العمليات X ، S ، L
X(T،K1)=FFFFFFFFFFFFFFFFFFFF99BB99FF99BB99
S(X(T،K1))=B6B6B6B6B6B6B6B6B6E87DE8B6E87DE8
L(S(X(T،K1)))=30081449922F4ACFA1B055E386B697E2

X(T1،K2)=DFC5BFC0F56A69CEB18201951E0C4B1C
S(X(T1،K2))=61AC3B07F47891E74524EE945F23A214
L(S(X(T1،K2)))=7290C6A158426FB396D562087A495E28

وهكذا ، ستبدو النتيجة النهائية كما يلي:
T10=CDEDD4B9428D465A3024BCBE909D677F
كتلة فك التشفير
لفك تشفير النص ، تحتاج إلى استخدام العمليات العكسية بالترتيب العكسي (انظر الشكل 2).
عملية XOR معكوسة لنفسها ، وعكس العملية S هي الاستبدال وفقًا للجدول التالي:
عكس الجدول التحول غير الخطيةالتحول العكسي إلى الدالة L سيكون:
a0=a15∗148+a14∗32+a13∗133+a12∗16+
+a11∗194+a10∗192+a9∗1+a8∗251+a7∗1+a6∗192+a5∗194+
+a4∗16+a3∗133+a2∗32+a1∗148+a0∗1
والتحول في اتجاه المستوى الأعلى. (كرر العملية 16 مرة)
تنفيذ جافا
أولاً ، نحدد الثوابت اللازمة
static final int BLOCK_SIZE = 16;
لنقم بإنشاء جميع الوظائف الرئيسية:
لتنفيذ الدالة L ، نحتاج إلى العديد من الوظائف المساعدة ، واحدة لحساب تكاثر الأرقام في حقل غالوا وواحد للتحول.
وظائف عكسية:
حسنا ، والوظيفة الرئيسية
static byte[] key_1 = {0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00, (byte) 0xff, (byte) 0xee, (byte) 0xdd, (byte) 0xcc, (byte) 0xbb, (byte) 0xaa, (byte) 0x99, (byte) 0x88}; static byte[] key_2 = {(byte) 0xef, (byte) 0xcd, (byte) 0xab, (byte) 0x89, 0x67, 0x45, 0x23, 0x01, 0x10, 0x32, 0x54, 0x76, (byte) 0x98, (byte) 0xba, (byte) 0xdc, (byte) 0xfe}; static byte[] blk = DatatypeConverter.parseHexBinary("8899aabbccddeeff0077665544332211"); public static void main(String[] args) { GOST_Kuz_Expand_Key(key_1, key_2); byte[] encriptBlok = GOST_Kuz_Encript(blk); System.out.println(DatatypeConverter.printHexBinary(encriptBlok)); byte[] decriptBlok = GOST_Kuz_Decript(encriptBlok); System.out.println(DatatypeConverter.printHexBinary(decriptBlok)); }
لقد تعلمنا تشفير كتلة البيانات من أجل تشفير النص الذي طوله أطول من طول الكتلة ؛ هناك العديد من الأوضاع الموضحة في المعيار - GOST 34.13-2015:
- وضع الاستبدال البسيط (Codebook Electronic، ECB) ؛
- وضع جاما (عداد ، نسبة النقر إلى الظهور) ؛
- وضع جاما مع ردود فعل الإخراج (ردود الفعل الإخراج ، OFB) ؛
- استبدال بسيط وضع تستعد (تشفير كتلة تسلسل ، CBC) ؛
- وضع جاما مع ردود الفعل في النص المشفر (ملاحظات التشفير ، CFB) ؛
- وضع رمز مصادقة الرسائل (MAC).
في جميع الأوضاع ، يجب أن يكون طول النص دائمًا مضاعفًا لطول الكتلة ، لذلك يتم دائمًا مبطن النص إلى اليمين ببت واحد واحد وأصفار إلى طول الكتلة.
أسهل وضع هو وضع الاستبدال البسيط. في هذا الوضع ، يتم تقسيم النص إلى كتل ، ثم يتم تشفير كل كتلة بشكل منفصل عن الباقي ، ثم يتم لصق كتل النص المشفر معًا ونحصل على رسالة مشفرة. هذا الوضع هو أبسط والأكثر ضعفا ويكاد لا يتم تطبيقه في الممارسة.
يمكن النظر في أوضاع أخرى بالتفصيل في وقت لاحق.