Threefish
מידע כללי
תכנון
Bruce Schneier, Niels Ferguson, Stefan Lucks, Doug Whiting, Mihir Bellare, Tadayoshi Kohno, Jon Callas, Jesse Walker
פרסום
2008
מבוסס על
Blowfish , Twofish
מבנה הצופן
אורך מפתח
256/512/1024 סיביות
אורך בלוק
זהה לאורך המפתח
מבנה
ARX
מספר סבבים
72 (במפתח 1024 יש 80 סבבים)
Threefish [1] הוא צופן בלוקים בר התאמה (tweakable block cipher) שפותח ב-2008 כחלק מפונקציית הגיבוב Skein [2] שהוצעה לתחרות הגיבוב של NIST . הצופן מגיע בשלוש גרסאות לפי גודל בלוק; 256, 512 או 1024 סיביות ואורכו של מפתח ההצפנה כאורך הבלוק. הוא כולל tweak שהוא מעין וקטור אתחול בגודל 128 סיביות.
ליבת צופן Threefish הנקראת MIX, בנויה בסגנון ARX המורכבת משלוש פעולות בסיסיות, חיבור מודולו
2
64
{\displaystyle 2^{64}}
, XOR והזזה מעגלית בהיסטים קבועים. הקונספט הוא פעולות פשוטות עם יותר סבבים, בניגוד לצפנים אחרים בהם הפעולות מורכבות יותר אך עם פחות סבבים. כל הפעולות הן על מילים בגודל 64 סיביות. כאשר בצופן Threefish-256 ו-Threefish-512 הליבה מופעלת 72 פעמים בתשעה סבבים (שמונה פעמים לסבב) ואילו ב-Threefhish-1024 הליבה מופעלת 80 פעם בעשרה סבבים. בכל סבב מופעלת הפונקציה MIX שמונה פעמים, בנוסף מבוצעת תמורה של כל מילות הזיכרון הפנימי על ידי הזזה מעגלית לפי היסטים קבועים להשגת אפקט פיזור גבוה וכן אחת לארבעה סבבים מוסיפים חלק מהמפתח. בשל פשטותו הרבה הצופן מהיר מאוד ויכול להגיע לקצב של 6.5 cpb (על מחשב 64 ביט ).
תיאור ארבעה סבבים מתוך 72 הסבבים של Threefish-512 הכוללים שילוב של הפונקציה MIX, התמורה
π
{\displaystyle \pi }
ושילוב מפתח ההצפנה אחת לארבעה סבבים
Threefish פותח על ידי Mihir Bellare, Jesse Walker, Jon Callas, Doug Whiting, Stefan Lucks, Niels Ferguson, Bruce Schneier, Tadayoshi Kohno והוא אינו רשום כפטנט , קוד המקור אינו מוגן בזכויות יוצרים והוא חופשי לשימוש לכל מטרה.
תיאור הצופן
הפונקציה MIX
כל פעולות הצופן הן על מילים בגודל 64 סיביות המייצגות מספרים שלמים חיוביים (לא מסומנים) בטווח
[
0..2
64
−
1
]
{\displaystyle [0..2^{64}-1]}
. אם הקלט הוא מערך בתים יש להמירו למילים בגודל 64 סיביות בשיטת סדר בתים קטן (להלן). דהיינו הבית הפחות משמעותי מאוחסן בכתובת הראשונה בזיכרון.
פונקציית ההצפנה
E
(
K
,
T
,
P
)
{\displaystyle E(K,T,P)}
מקבלת את הארגומנטים הבאים:
K . מפתח הצפנה סודי המסופק על ידי המשתמש שהוא מחרוזת באורך
N
w
{\displaystyle N_{w}}
מילים כאשר
N
w
∈
{
32
,
64
,
128
}
{\displaystyle N_{w}\in \{32,64,128\}}
.
T . ערך ייחודי שנקרא Tweak באורך 16 בתים.
P . טקסט גלוי באורך זהה למפתח.
את מפתח ההצפנה הסודי וה-tweak מאריכים תחילה במילה נוספת שנקראת זוגיות (parity) שהיא תוצאת XOR של כל מילות המפתח וה-tweak בהתאמה ומחלקים לתת-מפתחות עבור כל הסבבים. כל תת-מפתח הוא שילוב של כל מילות המפתח המורחב למעט אחת, שתים מתוך שלוש מילות tweak ומספר סידורי של תת-המפתח (כמתואר בתרשים הכנת המפתח). כל תהליך הכנת המפתח ניתן לביצוע במספר מחזורי שעון מועט. עובדה קריטית אם הצופן אמור להיות חלק מפונקציית גיבוב. כאשר מגבבים כמות גדולה של בלוקים, כל בלוק צריך להיות מוצפן בנפרד (עם מפתח שונה), על כן תהליך הכנה ארוך עבור כל הצפנה אינו יעיל.
המפתח
K
{\displaystyle K}
מיוצג כמערך מילים:
k
0
,
k
1
,
.
.
.
,
k
N
w
−
1
{\displaystyle k_{0},k_{1},...,k_{N_{w}-1}}
באורך
N
w
{\displaystyle N_{w}}
ומילה נוספת לזוגיות, ה-tweak מוצג כשתי מילים:
t
0
,
t
1
{\displaystyle t_{0},t_{1}}
ומילה נוספת לזוגיות וטקסט המקור
P
{\displaystyle P}
הוא מערך המילים
p
0
,
p
1
,
.
.
.
,
p
N
w
−
1
{\displaystyle p_{0},p_{1},...,p_{N_{w}-1}}
. מספר הסבבים
N
r
{\displaystyle N_{r}}
הוא פונקציה של גודל הבלוק כמוצג בטבלה.
גודל בלוק/מפתח
מספר המילים
מספר פעמים שהפונקציה MIX מופעלת
מספר סבבים
256
4
72
8
512
8
72
8
1024
16
80
10
הפונקציה להוספת המפתח מקבלת מערך של
N
r
/
4
+
1
{\displaystyle N_{r}/4+1}
תת-מפתחות, כל אחד בגודל
N
w
{\displaystyle N_{w}}
מילים. את המילים המתאימות לסבב
s
{\displaystyle s}
מסמנים
k
s
,
0
,
k
s
,
1
,
.
.
.
,
k
s
,
N
w
−
1
{\displaystyle k_{s,0},k_{s,1},...,k_{s,N_{w}-1}}
. השילוב נעשה באופן הבא; יהי
v
{\displaystyle v}
מערך עזר של תוצאת הביניים, הביטוי
v
d
,
i
{\displaystyle v_{d,i}}
הוא המילה ה-
i
{\displaystyle i}
לאחר
d
{\displaystyle d}
סבבים.
תחילה טוענים את
N
w
{\displaystyle N_{w}}
הבתים של המסר כך:
For
i
=
0
to
N
w
−
1
do
{\displaystyle {\text{For }}i=0{\text{ to }}N_{w}-1{\text{ do}}}
v
0
,
i
=
p
i
{\displaystyle v_{0,i}=p_{i}}
לאחר מכן מבוצעים
N
r
−
1
{\displaystyle N_{r}-1}
סבבים כשבכל אחד מהם מוסיפים תת-מפתח רק אם
d
mod
4
=
0
{\displaystyle d{\text{ mod }}4=0}
(אחת לארבעה סבבים) לסיכום:
e
d
,
i
=
{
(
v
d
,
i
+
k
d
/
4
,
i
)
mod
2
64
,
if
d
mod
4
=
0
v
d
,
i
,
otherwise
{\displaystyle e_{d,i}={\begin{cases}(v_{d,i}+k_{d/4,i}){\text{ mod }}2^{64},&{\mbox{if }}d{\text{ mod }}4=0\\v_{d,i},&{\mbox{ otherwise }}\end{cases}}}
את הערבוב MIX והתמורה
π
{\displaystyle \pi }
(בטבלה הבאה) מבצעים לסירוגין כדלהלן:
For
j
=
0
to
N
w
/
2
−
1
do
{\displaystyle {\text{For }}j=0{\text{ to }}N_{w}/2-1{\text{ do}}}
(
f
d
,
2
j
,
f
d
,
2
j
+
1
)
←
MIX
d
,
j
(
e
d
,
2
j
,
e
d
,
2
j
+
1
)
{\displaystyle (f_{d,2j},f_{d,2j+1})\leftarrow {\text{MIX}}_{d,j}(e_{d,2j},e_{d,2j+1})}
For
i
=
0
to
N
w
−
1
do
{\displaystyle {\text{For }}i=0{\text{ to }}N_{w}-1{\text{ do}}}
v
d
+
1
,
i
=
f
d
,
π
(
i
)
{\displaystyle v_{d+1,i}=f_{d,\pi (i)}}
והטקסט המוצפן מתקבל על ידי:
For
i
=
0
to
N
w
−
1
do
{\displaystyle {\text{For }}i=0{\text{ to }}N_{w}-1{\text{ do}}}
c
i
=
(
v
N
r
,
i
+
k
N
r
/
4
,
i
)
mod
2
64
{\displaystyle c_{i}=(v_{N_{r},i}+k_{N_{r}/4,i}){\text{ mod }}2^{64}}
טבלת תמורות
π
{\displaystyle \pi }
להלן טבלת התמורות המייצגת את הסידור מחדש של מילות הקלט לפי גודל הצופן. לדוגמה במקרה של Threefish-256 ישנן ארבע מילים ולכן התמורות הן לפי השורה הראשונה, לכן
v
5
,
3
=
f
4
,
π
(
3
)
{\displaystyle v_{5,3}=f_{4,\pi (3)}}
פירושו שהמילה הראשונה מהסבב הרביעי תהיה שלישית בסבב החמישי.
טבלת תמורות
π
(
i
)
{\displaystyle {\boldsymbol {\pi (i)}}}
i
{\displaystyle i}
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
N
w
=
4
{\displaystyle N_{w}=4}
0
3
2
1
N
w
=
8
{\displaystyle N_{w}=8}
2
1
4
7
6
5
0
3
N
w
=
16
{\displaystyle N_{w}=16}
0
9
2
13
6
11
4
15
10
7
12
3
14
5
8
1
הפונקציה MIX
הפונקציה
MIX
d
,
j
{\displaystyle {\text{MIX}}_{d,j}}
מקבלת שתי מילות קלט
(
x
0
,
x
1
)
{\displaystyle (x_{0},x_{1})}
ומייצרת שתי מילות פלט
(
y
0
,
y
1
)
{\displaystyle (y_{0},y_{1})}
לפי הנוסחה הבאה:
y
0
=
(
x
0
+
x
1
)
mod
2
64
{\displaystyle y_{0}=(x_{0}+x_{1}){\text{ mod }}2^{64}}
y
1
=
(
x
1
⋘
R
(
d
mod
8
)
,
j
)
⊕
y
0
{\displaystyle y_{1}=(x_{1}\lll R_{(d{\text{ mod }}8),j})\oplus y_{0}}
הסימן
⋘
{\displaystyle \lll }
מייצג אופרטור הזזה מעגלית לשמאל. הקבועים
R
d
,
j
{\displaystyle R_{d,j}}
הם לפי טבלת ההיסטים הבאה. חלק מהקבועים שונו בגרסה 2 של הצופן.
טבלת ההיסטים
N
w
{\displaystyle N_{w}}
4
8
16
j
0
1
0
1
2
3
0
1
2
3
4
5
6
7
0
14
16
46
36
19
37
24
13
8
47
8
17
22
37
1
52
57
33
27
14
42
38
19
10
55
49
18
23
52
2
23
40
17
49
36
39
33
4
51
13
34
41
59
17
d=3
5
37
44
9
54
56
5
20
48
41
47
28
16
25
4
25
33
39
30
34
24
41
9
37
31
12
47
44
30
5
46
12
13
50
10
17
16
34
56
51
4
53
42
41
6
58
22
25
29
39
43
31
44
47
46
19
42
44
25
7
32
32
8
35
56
22
9
48
35
52
23
31
37
20
פרוצדורת הרחבת מפתח
פרוצדורת הכנת תת-מפתחות של Threefish
תחילה מוסיפים שתי מילים.
k
N
w
=
C
240
⊕
⨁
i
=
0
N
w
−
1
k
i
{\displaystyle k_{N_{w}}=C_{240}\oplus \bigoplus _{i=0}^{N_{w}-1}k_{i}}
וכן
t
2
=
t
0
⊕
t
1
{\displaystyle t_{2}=t_{0}\oplus t_{1}}
.
כלומר מילת מפתח נוספת שהיא XOR של כל מילות המפתח וכן מילה נוספת שהיא XOR של שתי המילים של ה-tweak. הקבוע
C
240
=
0x1BD11BDAA9FC1A22
{\displaystyle C_{240}={\text{0x1BD11BDAA9FC1A22}}}
מבטיח שהמפתח המורחב לא יהיה כולו או כמעט כולו אפס. הקבוע הזה נוצר על ידי הצפנה של המספר "240" עם צופן AES כאשר המפתח כולו אפס. הוספת ה-tweak היא כדלהלן:
k
s
,
i
=
{
k
(
s
+
i
)
mod
(
N
w
+
1
)
,
for
i
=
0
,
.
.
.
,
N
w
−
4
k
(
s
+
i
)
mod
(
N
w
+
1
)
+
t
s
mod
3
,
for
i
=
N
w
−
3
k
(
s
+
i
)
mod
(
N
w
+
1
)
+
t
(
s
+
1
)
mod
3
,
for
i
=
N
w
−
2
k
(
s
+
i
)
mod
(
N
w
+
1
)
+
s
,
for
i
=
N
w
−
1
{\displaystyle k_{s,i}={\begin{cases}k_{(s+i){\text{ mod }}(N_{w}+1)},&{\text{for }}i=0,...,N_{w}-4\\k_{(s+i){\text{ mod }}(N_{w}+1)}+t_{s{\text{ mod }}3},&{\text{for }}i=N_{w}-3\\k_{(s+i){\text{ mod }}(N_{w}+1)}+t_{(s+1){\text{ mod }}3},&{\text{for }}i=N_{w}-2\\k_{(s+i){\text{ mod }}(N_{w}+1)}+s,&{\text{for }}i=N_{w}-1\end{cases}}}
כל פעולות החיבור הן מודולו
2
64
{\displaystyle 2^{64}}
.
פענוח
הפענוח מתבצע בדרך ההפוכה, עם תת-מפתחות בסדר הפוך, תמורה הופכית ופונקציית MIX הפוכה. להלן קוד לדוגמה. יש לציין שאם הצופן מהווה חלק מפונקציית גיבוב אין צורך בפונקציית פענוח כלל.
פסאודו-קוד
הקוד הבא מתאר הצפנה ופענוח עם Threefish-512. פונקציית הכנת המפתח מקבלת מערך
K
{\displaystyle K}
באורך 9 מילים ו-tweak באורך 3 מילים ומוסיפה את מילות הזוגיות (parity). תחילה מציבים את המפתח הסודי של המשתמש ב-8 הכניסות הראשונות של המערך
K
{\displaystyle K}
ואת שתי מילות ה-tweak בשתי הכניסות הראשונות של
T
{\displaystyle T}
ומבצעים כדלהלן.
הכנת מפתח
T
h
r
e
e
f
i
s
h
.
K
e
y
S
e
t
u
p
(
K
)
{\displaystyle \mathbf {Threefish.KeySetup} (K)}
{
{\displaystyle \{}
K
[
8
]
=
K
[
0
]
⊕
K
[
1
]
⊕
K
[
2
]
⊕
K
[
3
]
⊕
K
[
4
]
⊕
K
[
5
]
⊕
K
[
6
]
⊕
K
[
7
]
⊕
C
240
{\displaystyle K[8]=K[0]\ \oplus \ K[1]\ \oplus \ K[2]\ \oplus \ K[3]\ \oplus \ K[4]\ \oplus \ K[5]\ \oplus \ K[6]\ \oplus \ K[7]\ \oplus \ C_{240}}
T
[
2
]
=
T
[
0
]
⊕
T
[
1
]
{\displaystyle T[2]=T[0]\ \oplus \ T[1]}
}
{\displaystyle \}}
הצפנה
פונקציית ההצפנה מקבלת מערך
P
{\displaystyle P}
באורך 8 מילים, tweak המסומן ב-
T
{\displaystyle T}
באורך 3 מילים ומפתח סודי
K
{\displaystyle K}
באורך 9 מילים ומחזירה מערך
C
{\displaystyle C}
באורך 8 מילים. הקוד הבא לקוח מקוד היישום שהומלץ לתקן על ידי המפתחים ממנו הוסרו קטעי קוד לא חשובים למען הפשטות. הקוד מתוכנן בשיטת פרישת לולאות (loop unrolling) חלקית, פרישת לולאות מקובלת בכתיבת קודים ממוטבים למעבדי 32 ו-64 סיביות. כאן מספר הלולאות צומצם ל-9 וכן בדוגמה זו ההנחה היא שההמרות הן לפי סדר בתים קטן, כלומר מחרוזת הבתים המייצגת את הטקסט המקורי מומרת לפי הנוסחה להלן ל-
P
=
P
[
0
]
,
P
[
1
]
,
.
.
.
,
P
[
7
]
{\displaystyle P=P[0],P[1],...,P[7]}
שהוא מערך של 8 מספרים שלמים בגודל 64 סיביות מהקטן לגדול (המספר הראשון מאוחסן בכתובת
P
[
0
]
{\displaystyle P[0]}
וכן הלאה). באותה שיטה ממירים את הפרמטרים האחרים.
T
h
r
e
e
f
i
s
h
.
E
n
c
r
y
p
t
(
P
,
T
,
K
)
{\displaystyle \mathbf {Threefish.Encrypt} {\boldsymbol {(P,T,K)}}}
For
i
=
0
to
7
do
{\displaystyle {\text{For }}i=0{\text{ to }}7{\text{ do }}}
C
[
i
]
=
P
[
i
]
+
K
[
i
]
{\displaystyle \ \ \ \ C[i]=P[i]+K[i]}
C
[
5
]
=
C
[
5
]
+
T
[
0
]
{\displaystyle C[5]=C[5]+T[0]}
C
[
6
]
=
C
[
6
]
+
T
[
1
]
{\displaystyle C[6]=C[6]+T[1]}
For
r
=
1
to
9
do
{\displaystyle {\text{For }}r=1{\text{ to }}9{\text{ do }}}
{
{\displaystyle \{}
C
[
0
]
=
C
[
0
]
+
C
[
1
]
,
C
[
1
]
=
ROL
(
C
[
1
]
,
46
)
,
C
[
1
]
=
C
[
1
]
⊕
C
[
0
]
{\displaystyle C[0]=C[0]+C[1],\ \ C[1]={\text{ROL}}(C[1],46),\ \ C[1]=C[1]\oplus C[0]}
C
[
2
]
=
C
[
2
]
+
C
[
3
]
,
C
[
3
]
=
ROL
(
C
[
3
]
,
36
)
,
C
[
3
]
=
C
[
3
]
⊕
C
[
2
]
{\displaystyle C[2]=C[2]+C[3],\ \ C[3]={\text{ROL}}(C[3],36),\ \ C[3]=C[3]\oplus C[2]}
C
[
4
]
=
C
[
4
]
+
C
[
5
]
,
C
[
5
]
=
ROL
(
C
[
5
]
,
19
)
,
C
[
5
]
=
C
[
5
]
⊕
C
[
4
]
{\displaystyle C[4]=C[4]+C[5],\ \ C[5]={\text{ROL}}(C[5],19),\ \ C[5]=C[5]\oplus C[4]}
C
[
6
]
=
C
[
6
]
+
C
[
7
]
,
C
[
7
]
=
ROL
(
C
[
7
]
,
37
)
,
C
[
7
]
=
C
[
7
]
⊕
C
[
6
]
{\displaystyle C[6]=C[6]+C[7],\ \ C[7]={\text{ROL}}(C[7],37),\ \ C[7]=C[7]\oplus C[6]}
C
[
2
]
=
C
[
2
]
+
C
[
1
]
,
C
[
1
]
=
ROL
(
C
[
1
]
,
33
)
,
C
[
1
]
=
C
[
1
]
⊕
C
[
2
]
{\displaystyle C[2]=C[2]+C[1],\ \ C[1]={\text{ROL}}(C[1],33),\ \ C[1]=C[1]\oplus C[2]}
C
[
4
]
=
C
[
4
]
+
C
[
7
]
,
C
[
7
]
=
ROL
(
C
[
7
]
,
27
)
,
C
[
7
]
=
C
[
7
]
⊕
C
[
4
]
{\displaystyle C[4]=C[4]+C[7],\ \ C[7]={\text{ROL}}(C[7],27),\ \ C[7]=C[7]\oplus C[4]}
C
[
6
]
=
C
[
6
]
+
C
[
5
]
,
C
[
5
]
=
ROL
(
C
[
5
]
,
14
)
,
C
[
5
]
=
C
[
5
]
⊕
C
[
6
]
{\displaystyle C[6]=C[6]+C[5],\ \ C[5]={\text{ROL}}(C[5],14),\ \ C[5]=C[5]\oplus C[6]}
C
[
0
]
=
C
[
0
]
+
C
[
3
]
,
C
[
3
]
=
ROL
(
C
[
3
]
,
42
)
,
C
[
3
]
=
C
[
3
]
⊕
C
[
0
]
{\displaystyle C[0]=C[0]+C[3],\ \ C[3]={\text{ROL}}(C[3],42),\ \ C[3]=C[3]\oplus C[0]}
C
[
4
]
=
C
[
4
]
+
C
[
1
]
,
C
[
1
]
=
ROL
(
C
[
1
]
,
17
)
,
C
[
1
]
=
C
[
1
]
⊕
C
[
4
]
{\displaystyle C[4]=C[4]+C[1],\ \ C[1]={\text{ROL}}(C[1],17),\ \ C[1]=C[1]\oplus C[4]}
C
[
6
]
=
C
[
6
]
+
C
[
3
]
,
C
[
3
]
=
ROL
(
C
[
3
]
,
49
)
,
C
[
3
]
=
C
[
3
]
⊕
C
[
6
]
{\displaystyle C[6]=C[6]+C[3],\ \ C[3]={\text{ROL}}(C[3],49),\ \ C[3]=C[3]\oplus C[6]}
C
[
0
]
=
C
[
0
]
+
C
[
5
]
,
C
[
5
]
=
ROL
(
C
[
5
]
,
36
)
,
C
[
5
]
=
C
[
5
]
⊕
C
[
0
]
{\displaystyle C[0]=C[0]+C[5],\ \ C[5]={\text{ROL}}(C[5],36),\ \ C[5]=C[5]\oplus C[0]}
C
[
2
]
=
C
[
2
]
+
C
[
7
]
,
C
[
7
]
=
ROL
(
C
[
7
]
,
39
)
,
C
[
7
]
=
C
[
7
]
⊕
C
[
2
]
{\displaystyle C[2]=C[2]+C[7],\ \ C[7]={\text{ROL}}(C[7],39),\ \ C[7]=C[7]\oplus C[2]}
C
[
6
]
=
C
[
6
]
+
C
[
1
]
,
C
[
1
]
=
ROL
(
C
[
1
]
,
44
)
,
C
[
1
]
=
C
[
1
]
⊕
C
[
6
]
{\displaystyle C[6]=C[6]+C[1],\ \ C[1]={\text{ROL}}(C[1],44),\ \ C[1]=C[1]\oplus C[6]}
C
[
0
]
=
C
[
0
]
+
C
[
7
]
,
C
[
7
]
=
ROL
(
C
[
7
]
,
9
)
,
C
[
7
]
=
C
[
7
]
⊕
C
[
0
]
{\displaystyle C[0]=C[0]+C[7],\ \ C[7]={\text{ROL}}(C[7],9),\ \ C[7]=C[7]\oplus C[0]}
C
[
2
]
=
C
[
2
]
+
C
[
5
]
,
C
[
5
]
=
ROL
(
C
[
5
]
,
54
)
,
C
[
5
]
=
C
[
5
]
⊕
C
[
2
]
{\displaystyle C[2]=C[2]+C[5],\ \ C[5]={\text{ROL}}(C[5],54),\ \ C[5]=C[5]\oplus C[2]}
C
[
4
]
=
C
[
4
]
+
C
[
3
]
,
C
[
3
]
=
ROL
(
C
[
3
]
,
56
)
,
C
[
3
]
=
C
[
3
]
⊕
C
[
4
]
{\displaystyle C[4]=C[4]+C[3],\ \ C[3]={\text{ROL}}(C[3],56),\ \ C[3]=C[3]\oplus C[4]}
For
i
=
0
to
7
do
C
[
i
]
=
C
[
i
]
+
K
[
(
(
2
⋅
r
−
1
)
+
i
)
mod
9
]
{\displaystyle {\text{For }}i=0{\text{ to }}7{\text{ do }}C[i]=C[i]+K[((2\cdot r-1)+i){\text{ mod }}9]}
C
[
5
]
=
C
[
5
]
+
T
[
(
2
⋅
r
−
1
)
mod
3
]
{\displaystyle C[5]=C[5]+T[(2\cdot r-1){\text{ mod }}3]}
C
[
6
]
=
C
[
6
]
+
T
[
(
2
⋅
r
)
mod
3
]
{\displaystyle C[6]=C[6]+T[(2\cdot r){\text{ mod }}3]}
C
[
7
]
=
C
[
7
]
+
(
2
⋅
r
−
1
)
{\displaystyle C[7]=C[7]+(2\cdot r-1)}
C
[
0
]
=
C
[
0
]
+
C
[
1
]
,
C
[
1
]
=
ROL
(
C
[
1
]
,
39
)
,
C
[
1
]
=
C
[
1
]
⊕
C
[
0
]
{\displaystyle C[0]=C[0]+C[1],\ \ C[1]={\text{ROL}}(C[1],39),\ \ C[1]=C[1]\oplus C[0]}
C
[
2
]
=
C
[
2
]
+
C
[
3
]
,
C
[
3
]
=
ROL
(
C
[
3
]
,
30
)
,
C
[
3
]
=
C
[
3
]
⊕
C
[
2
]
{\displaystyle C[2]=C[2]+C[3],\ \ C[3]={\text{ROL}}(C[3],30),\ \ C[3]=C[3]\oplus C[2]}
C
[
4
]
=
C
[
4
]
+
C
[
5
]
,
C
[
5
]
=
ROL
(
C
[
5
]
,
34
)
,
C
[
5
]
=
C
[
5
]
⊕
C
[
4
]
{\displaystyle C[4]=C[4]+C[5],\ \ C[5]={\text{ROL}}(C[5],34),\ \ C[5]=C[5]\oplus C[4]}
C
[
6
]
=
C
[
6
]
+
C
[
7
]
,
C
[
7
]
=
ROL
(
C
[
7
]
,
24
)
,
C
[
7
]
=
C
[
7
]
⊕
C
[
6
]
{\displaystyle C[6]=C[6]+C[7],\ \ C[7]={\text{ROL}}(C[7],24),\ \ C[7]=C[7]\oplus C[6]}
C
[
2
]
=
C
[
2
]
+
C
[
1
]
,
C
[
1
]
=
ROL
(
C
[
1
]
,
13
)
,
C
[
1
]
=
C
[
1
]
⊕
C
[
2
]
{\displaystyle C[2]=C[2]+C[1],\ \ C[1]={\text{ROL}}(C[1],13),\ \ C[1]=C[1]\oplus C[2]}
C
[
4
]
=
C
[
4
]
+
C
[
7
]
,
C
[
7
]
=
ROL
(
C
[
7
]
,
50
)
,
C
[
7
]
=
C
[
7
]
⊕
C
[
4
]
{\displaystyle C[4]=C[4]+C[7],\ \ C[7]={\text{ROL}}(C[7],50),\ \ C[7]=C[7]\oplus C[4]}
C
[
6
]
=
C
[
6
]
+
C
[
5
]
,
C
[
5
]
=
ROL
(
C
[
5
]
,
10
)
,
C
[
5
]
=
C
[
5
]
⊕
C
[
6
]
{\displaystyle C[6]=C[6]+C[5],\ \ C[5]={\text{ROL}}(C[5],10),\ \ C[5]=C[5]\oplus C[6]}
C
[
0
]
=
C
[
0
]
+
C
[
3
]
,
C
[
3
]
=
ROL
(
C
[
3
]
,
17
)
,
C
[
3
]
=
C
[
3
]
⊕
C
[
0
]
{\displaystyle C[0]=C[0]+C[3],\ \ C[3]={\text{ROL}}(C[3],17),\ \ C[3]=C[3]\oplus C[0]}
C
[
4
]
=
C
[
4
]
+
C
[
1
]
,
C
[
1
]
=
ROL
(
C
[
1
]
,
25
)
,
C
[
1
]
=
C
[
1
]
⊕
C
[
4
]
{\displaystyle C[4]=C[4]+C[1],\ \ C[1]={\text{ROL}}(C[1],25),\ \ C[1]=C[1]\oplus C[4]}
C
[
6
]
=
C
[
6
]
+
C
[
3
]
,
C
[
3
]
=
ROL
(
C
[
3
]
,
29
)
,
C
[
3
]
=
C
[
3
]
⊕
C
[
6
]
{\displaystyle C[6]=C[6]+C[3],\ \ C[3]={\text{ROL}}(C[3],29),\ \ C[3]=C[3]\oplus C[6]}
C
[
0
]
=
C
[
0
]
+
C
[
5
]
,
C
[
5
]
=
ROL
(
C
[
5
]
,
39
)
,
C
[
5
]
=
C
[
5
]
⊕
C
[
0
]
{\displaystyle C[0]=C[0]+C[5],\ \ C[5]={\text{ROL}}(C[5],39),\ \ C[5]=C[5]\oplus C[0]}
C
[
2
]
=
C
[
2
]
+
C
[
7
]
,
C
[
7
]
=
ROL
(
C
[
7
]
,
43
)
,
C
[
7
]
=
C
[
7
]
⊕
C
[
2
]
{\displaystyle C[2]=C[2]+C[7],\ \ C[7]={\text{ROL}}(C[7],43),\ \ C[7]=C[7]\oplus C[2]}
C
[
6
]
=
C
[
6
]
+
C
[
1
]
,
C
[
1
]
=
ROL
(
C
[
1
]
,
8
)
,
C
[
1
]
=
C
[
1
]
⊕
C
[
6
]
{\displaystyle C[6]=C[6]+C[1],\ \ C[1]={\text{ROL}}(C[1],8),\ \ C[1]=C[1]\oplus C[6]}
C
[
0
]
=
C
[
0
]
+
C
[
7
]
,
C
[
7
]
=
ROL
(
C
[
7
]
,
35
)
,
C
[
7
]
=
C
[
7
]
⊕
C
[
0
]
{\displaystyle C[0]=C[0]+C[7],\ \ C[7]={\text{ROL}}(C[7],35),\ \ C[7]=C[7]\oplus C[0]}
C
[
2
]
=
C
[
2
]
+
C
[
5
]
,
C
[
5
]
=
ROL
(
C
[
5
]
,
56
)
,
C
[
5
]
=
C
[
5
]
⊕
C
[
2
]
{\displaystyle C[2]=C[2]+C[5],\ \ C[5]={\text{ROL}}(C[5],56),\ \ C[5]=C[5]\oplus C[2]}
C
[
4
]
=
C
[
4
]
+
C
[
3
]
,
C
[
3
]
=
ROL
(
C
[
3
]
,
22
)
,
C
[
3
]
=
C
[
3
]
⊕
C
[
4
]
{\displaystyle C[4]=C[4]+C[3],\ \ C[3]={\text{ROL}}(C[3],22),\ \ C[3]=C[3]\oplus C[4]}
For
i
=
0
to
7
do
C
[
i
]
=
C
[
i
]
+
K
[
(
(
2
⋅
r
)
+
i
)
mod
9
]
{\displaystyle {\text{For }}i=0{\text{ to }}7{\text{ do }}C[i]=C[i]+K[((2\cdot r)+i){\text{ mod }}9]}
C
[
5
]
=
C
[
5
]
+
T
[
(
2
⋅
r
)
mod
3
]
{\displaystyle C[5]=C[5]+T[(2\cdot r){\text{ mod }}3]}
C
[
6
]
=
C
[
6
]
+
T
[
(
(
2
⋅
r
)
+
1
)
mod
3
]
{\displaystyle C[6]=C[6]+T[((2\cdot r)+1){\text{ mod }}3]}
C
[
7
]
=
C
[
7
]
+
(
2
⋅
r
)
{\displaystyle C[7]=C[7]+(2\cdot r)}
}
{\displaystyle \}}
Return
C
{\displaystyle {\text{Return }}C}
פונקציות עזר
כל פעולות החיבור הן כאמור מודולו
2
64
{\displaystyle 2^{64}}
כלומר נוטלים את 64 הסיביות הראשונות של התוצאה ומהיתר מתעלמים. התקן במעבדים רבים הוא שחיבור שלמים מתבצע באופן עקיף מודולו גבולות המילה, כלומר כל תוצאה שחורגת מהגודל שנכנס באוגר נחתכת ממילא, כך שאין צורך לנקוט בפעולה כלשהי. הפונקציה
ROR
{\displaystyle {\text{ROR}}}
היא הזזה מעגלית לימין והפונקציה
ROL
{\displaystyle {\text{ROL}}}
היא הזזה מעגלית לשמאל. אפשר ליישמן עם האופרטורים הרגילים; הזזה לשמאל "
≪
{\displaystyle \ll }
", הזזה לימין "
≫
{\displaystyle \gg }
" ואופרטור וגם "
∧
{\displaystyle \land }
", למשל ב-64 סיביות זה ייראה כך:
R
O
R
(
X
,
N
)
=
(
X
≫
(
N
∧
63
)
)
|
(
X
≪
(
(
64
−
N
)
∧
63
)
)
{\displaystyle \mathbf {ROR} (X,N)=(X\gg (N\land 63))\ |\ (X\ll ((64-N)\land 63))}
R
O
L
(
X
,
N
)
=
(
X
≪
(
N
∧
63
)
)
|
(
X
≫
(
(
64
−
N
)
∧
63
)
)
{\displaystyle \mathbf {ROL} (X,N)=(X\ll (N\land 63))\ |\ (X\gg ((64-N)\land 63))}
המרת מערכי בתים למילים וההפך מתבצעת לפי סדר בתים קטן כך:
T
o
I
n
t
(
b
0
,
b
1
,
.
.
.
,
b
n
−
1
)
=
∑
i
=
0
n
−
1
b
i
⋅
256
i
{\displaystyle \textstyle \mathbf {ToInt} (b_{0},b_{1},...,b_{n-1})=\sum _{i=0}^{n-1}b_{i}\cdot 256^{i}}
T
o
B
y
t
e
s
(
v
,
n
)
=
b
0
,
b
1
,
.
.
.
,
b
n
−
1
,
where
b
i
=
⌈
v
256
i
⌉
mod
256
{\displaystyle \textstyle \mathbf {ToBytes} (v,n)=b_{0},b_{1},...,b_{n-1},{\text{ where }}b_{i}=\left\lceil {\frac {v}{256^{i}}}\right\rceil {\text{ mod }}256}
פונקציית פענוח
פונקציית הפענוח מבצעת את כל הפעולות למעט XOR שהיא הופכית של עצמה, בסדר הפוך; חיסור מודולו
2
64
{\displaystyle 2^{64}}
במקום חיבור, הזזה מעגלית לימין במקום לשמאל והוספת מפתח מהסוף להתחלה. הפונקציה מקבלת את המערך
C
{\displaystyle C}
באורך 8 מילים, וקטור אתחול
T
{\displaystyle T}
באורך 3 מילים ומפתח סודי
K
{\displaystyle K}
באורך 9 מילים ומחזירה את
P
{\displaystyle P}
באורך 8 מילים.
T
h
r
e
e
f
i
s
h
.
D
e
c
r
y
p
t
(
C
,
T
,
K
)
{\displaystyle \mathbf {Threefish.Decrypt} {\boldsymbol {(C,T,K)}}}
For
r
=
9
down to
1
do
{\displaystyle {\text{For }}r=9{\text{ down to }}1{\text{ do }}}
{
{\displaystyle \{}
C
[
7
]
=
C
[
7
]
−
(
2
⋅
r
)
{\displaystyle C[7]=C[7]-(2\cdot r)}
C
[
6
]
=
C
[
6
]
−
T
[
(
(
2
⋅
r
)
+
1
)
mod
3
]
{\displaystyle C[6]=C[6]-T[((2\cdot r)+1){\text{ mod }}3]}
C
[
5
]
=
C
[
5
]
−
T
[
(
2
⋅
r
)
mod
3
]
{\displaystyle C[5]=C[5]-T[(2\cdot r){\text{ mod }}3]}
For
i
=
0
to
7
do
C
[
i
]
=
C
[
i
]
−
K
[
(
(
2
⋅
r
)
+
i
)
mod
9
]
{\displaystyle {\text{For }}i=0{\text{ to }}7{\text{ do }}C[i]=C[i]-K[((2\cdot r)+i){\text{ mod }}9]}
C
[
3
]
=
C
[
3
]
⊕
C
[
4
]
,
C
[
3
]
=
ROR
(
C
[
3
]
,
22
)
,
C
[
4
]
=
C
[
4
]
−
C
[
3
]
{\displaystyle C[3]=C[3]\oplus C[4],\ \ C[3]={\text{ROR}}(C[3],22),\ \ C[4]=C[4]-C[3]}
C
[
5
]
=
C
[
5
]
⊕
C
[
2
]
,
C
[
5
]
=
ROR
(
C
[
5
]
,
56
)
,
C
[
2
]
=
C
[
2
]
−
C
[
5
]
{\displaystyle C[5]=C[5]\oplus C[2],\ \ C[5]={\text{ROR}}(C[5],56),\ \ C[2]=C[2]-C[5]}
C
[
7
]
=
C
[
7
]
⊕
C
[
0
]
,
C
[
7
]
=
ROR
(
C
[
7
]
,
35
)
,
C
[
0
]
=
C
[
0
]
−
C
[
7
]
{\displaystyle C[7]=C[7]\oplus C[0],\ \ C[7]={\text{ROR}}(C[7],35),\ \ C[0]=C[0]-C[7]}
C
[
1
]
=
C
[
1
]
⊕
C
[
6
]
,
C
[
1
]
=
ROR
(
C
[
1
]
,
8
)
,
C
[
6
]
=
C
[
6
]
−
C
[
1
]
{\displaystyle C[1]=C[1]\oplus C[6],\ \ C[1]={\text{ROR}}(C[1],8),\ \ C[6]=C[6]-C[1]}
C
[
7
]
=
C
[
7
]
⊕
C
[
2
]
,
C
[
7
]
=
ROR
(
C
[
7
]
,
43
)
,
C
[
2
]
=
C
[
2
]
−
C
[
7
]
{\displaystyle C[7]=C[7]\oplus C[2],\ \ C[7]={\text{ROR}}(C[7],43),\ \ C[2]=C[2]-C[7]}
C
[
5
]
=
C
[
5
]
⊕
C
[
0
]
,
C
[
5
]
=
ROR
(
C
[
5
]
,
39
)
,
C
[
0
]
=
C
[
0
]
−
C
[
5
]
{\displaystyle C[5]=C[5]\oplus C[0],\ \ C[5]={\text{ROR}}(C[5],39),\ \ C[0]=C[0]-C[5]}
C
[
3
]
=
C
[
3
]
⊕
C
[
6
]
,
C
[
3
]
=
ROR
(
C
[
3
]
,
29
)
,
C
[
6
]
=
C
[
6
]
−
C
[
3
]
{\displaystyle C[3]=C[3]\oplus C[6],\ \ C[3]={\text{ROR}}(C[3],29),\ \ C[6]=C[6]-C[3]}
C
[
1
]
=
C
[
1
]
⊕
C
[
4
]
,
C
[
1
]
=
ROR
(
C
[
1
]
,
25
)
,
C
[
4
]
=
C
[
4
]
−
C
[
1
]
{\displaystyle C[1]=C[1]\oplus C[4],\ \ C[1]={\text{ROR}}(C[1],25),\ \ C[4]=C[4]-C[1]}
C
[
3
]
=
C
[
3
]
⊕
C
[
0
]
,
C
[
3
]
=
ROR
(
C
[
3
]
,
17
)
,
C
[
0
]
=
C
[
0
]
−
C
[
3
]
{\displaystyle C[3]=C[3]\oplus C[0],\ \ C[3]={\text{ROR}}(C[3],17),\ \ C[0]=C[0]-C[3]}
C
[
5
]
=
C
[
5
]
⊕
C
[
6
]
,
C
[
5
]
=
ROR
(
C
[
5
]
,
10
)
,
C
[
6
]
=
C
[
6
]
−
C
[
5
]
{\displaystyle C[5]=C[5]\oplus C[6],\ \ C[5]={\text{ROR}}(C[5],10),\ \ C[6]=C[6]-C[5]}
C
[
7
]
=
C
[
7
]
⊕
C
[
4
]
,
C
[
7
]
=
ROR
(
C
[
7
]
,
50
)
,
C
[
4
]
=
C
[
4
]
−
C
[
7
]
{\displaystyle C[7]=C[7]\oplus C[4],\ \ C[7]={\text{ROR}}(C[7],50),\ \ C[4]=C[4]-C[7]}
C
[
1
]
=
C
[
1
]
⊕
C
[
2
]
,
C
[
1
]
=
ROR
(
C
[
1
]
,
13
)
,
C
[
2
]
=
C
[
2
]
−
C
[
1
]
{\displaystyle C[1]=C[1]\oplus C[2],\ \ C[1]={\text{ROR}}(C[1],13),\ \ C[2]=C[2]-C[1]}
C
[
7
]
=
C
[
7
]
⊕
C
[
6
]
,
C
[
7
]
=
ROR
(
C
[
7
]
,
24
)
,
C
[
6
]
=
C
[
6
]
−
C
[
7
]
{\displaystyle C[7]=C[7]\oplus C[6],\ \ C[7]={\text{ROR}}(C[7],24),\ \ C[6]=C[6]-C[7]}
C
[
5
]
=
C
[
5
]
⊕
C
[
4
]
,
C
[
5
]
=
ROR
(
C
[
5
]
,
34
)
,
C
[
4
]
=
C
[
4
]
−
C
[
5
]
{\displaystyle C[5]=C[5]\oplus C[4],\ \ C[5]={\text{ROR}}(C[5],34),\ \ C[4]=C[4]-C[5]}
C
[
3
]
=
C
[
3
]
⊕
C
[
2
]
,
C
[
3
]
=
ROR
(
C
[
3
]
,
30
)
,
C
[
2
]
=
C
[
2
]
−
C
[
3
]
{\displaystyle C[3]=C[3]\oplus C[2],\ \ C[3]={\text{ROR}}(C[3],30),\ \ C[2]=C[2]-C[3]}
C
[
1
]
=
C
[
1
]
⊕
C
[
0
]
,
C
[
1
]
=
ROR
(
C
[
1
]
,
39
)
,
C
[
0
]
=
C
[
0
]
−
C
[
1
]
{\displaystyle C[1]=C[1]\oplus C[0],\ \ C[1]={\text{ROR}}(C[1],39),\ \ C[0]=C[0]-C[1]}
C
[
7
]
=
C
[
7
]
−
(
2
⋅
r
−
1
)
{\displaystyle C[7]=C[7]-(2\cdot r-1)}
C
[
6
]
=
C
[
6
]
−
T
[
(
2
⋅
r
)
mod
3
]
{\displaystyle C[6]=C[6]-T[(2\cdot r){\text{ mod }}3]}
C
[
5
]
=
C
[
5
]
−
T
[
(
2
⋅
r
−
1
)
mod
3
]
{\displaystyle C[5]=C[5]-T[(2\cdot r-1){\text{ mod }}3]}
For
i
=
0
to
7
do
C
[
i
]
=
C
[
i
]
−
K
[
(
(
2
⋅
r
−
1
)
+
i
)
mod
9
]
{\displaystyle {\text{For }}i=0{\text{ to }}7{\text{ do }}C[i]=C[i]-K[((2\cdot r-1)+i){\text{ mod }}9]}
C
[
3
]
=
C
[
3
]
⊕
C
[
4
]
,
C
[
3
]
=
ROR
(
C
[
3
]
,
56
)
,
C
[
4
]
=
C
[
4
]
−
C
[
3
]
{\displaystyle C[3]=C[3]\oplus C[4],\ \ C[3]={\text{ROR}}(C[3],56),\ \ C[4]=C[4]-C[3]}
C
[
5
]
=
C
[
5
]
⊕
C
[
2
]
,
C
[
5
]
=
ROR
(
C
[
5
]
,
54
)
,
C
[
2
]
=
C
[
2
]
−
C
[
5
]
{\displaystyle C[5]=C[5]\oplus C[2],\ \ C[5]={\text{ROR}}(C[5],54),\ \ C[2]=C[2]-C[5]}
C
[
7
]
=
C
[
7
]
⊕
C
[
0
]
,
C
[
7
]
=
ROR
(
C
[
7
]
,
9
)
,
C
[
0
]
=
C
[
0
]
−
C
[
7
]
{\displaystyle C[7]=C[7]\oplus C[0],\ \ C[7]={\text{ROR}}(C[7],9),\ \ C[0]=C[0]-C[7]}
C
[
1
]
=
C
[
1
]
⊕
C
[
6
]
,
C
[
1
]
=
ROR
(
C
[
1
]
,
44
)
,
C
[
6
]
=
C
[
6
]
−
C
[
1
]
{\displaystyle C[1]=C[1]\oplus C[6],\ \ C[1]={\text{ROR}}(C[1],44),\ \ C[6]=C[6]-C[1]}
C
[
7
]
=
C
[
7
]
⊕
C
[
2
]
,
C
[
7
]
=
ROR
(
C
[
7
]
,
39
)
,
C
[
2
]
=
C
[
2
]
−
C
[
7
]
{\displaystyle C[7]=C[7]\oplus C[2],\ \ C[7]={\text{ROR}}(C[7],39),\ \ C[2]=C[2]-C[7]}
C
[
5
]
=
C
[
5
]
⊕
C
[
0
]
,
C
[
5
]
=
ROR
(
C
[
5
]
,
36
)
,
C
[
0
]
=
C
[
0
]
−
C
[
5
]
{\displaystyle C[5]=C[5]\oplus C[0],\ \ C[5]={\text{ROR}}(C[5],36),\ \ C[0]=C[0]-C[5]}
C
[
3
]
=
C
[
3
]
⊕
C
[
6
]
,
C
[
3
]
=
ROR
(
C
[
3
]
,
49
)
,
C
[
6
]
=
C
[
6
]
−
C
[
3
]
{\displaystyle C[3]=C[3]\oplus C[6],\ \ C[3]={\text{ROR}}(C[3],49),\ \ C[6]=C[6]-C[3]}
C
[
1
]
=
C
[
1
]
⊕
C
[
4
]
,
C
[
1
]
=
ROR
(
C
[
1
]
,
17
)
,
C
[
4
]
=
C
[
4
]
−
C
[
1
]
{\displaystyle C[1]=C[1]\oplus C[4],\ \ C[1]={\text{ROR}}(C[1],17),\ \ C[4]=C[4]-C[1]}
C
[
3
]
=
C
[
3
]
⊕
C
[
0
]
,
C
[
3
]
=
ROR
(
C
[
3
]
,
42
)
,
C
[
0
]
=
C
[
0
]
−
C
[
3
]
{\displaystyle C[3]=C[3]\oplus C[0],\ \ C[3]={\text{ROR}}(C[3],42),\ \ C[0]=C[0]-C[3]}
C
[
5
]
=
C
[
5
]
⊕
C
[
6
]
,
C
[
5
]
=
ROR
(
C
[
5
]
,
14
)
,
C
[
6
]
=
C
[
6
]
−
C
[
5
]
{\displaystyle C[5]=C[5]\oplus C[6],\ \ C[5]={\text{ROR}}(C[5],14),\ \ C[6]=C[6]-C[5]}
C
[
7
]
=
C
[
7
]
⊕
C
[
4
]
,
C
[
7
]
=
ROR
(
C
[
7
]
,
27
)
,
C
[
4
]
=
C
[
4
]
−
C
[
7
]
{\displaystyle C[7]=C[7]\oplus C[4],\ \ C[7]={\text{ROR}}(C[7],27),\ \ C[4]=C[4]-C[7]}
C
[
1
]
=
C
[
1
]
⊕
C
[
2
]
,
C
[
1
]
=
ROR
(
C
[
1
]
,
33
)
,
C
[
2
]
=
C
[
2
]
−
C
[
1
]
{\displaystyle C[1]=C[1]\oplus C[2],\ \ C[1]={\text{ROR}}(C[1],33),\ \ C[2]=C[2]-C[1]}
C
[
7
]
=
C
[
7
]
⊕
C
[
6
]
,
C
[
7
]
=
ROR
(
C
[
7
]
,
37
)
,
C
[
6
]
=
C
[
6
]
−
C
[
7
]
{\displaystyle C[7]=C[7]\oplus C[6],\ \ C[7]={\text{ROR}}(C[7],37),\ \ C[6]=C[6]-C[7]}
C
[
5
]
=
C
[
5
]
⊕
C
[
4
]
,
C
[
5
]
=
ROR
(
C
[
5
]
,
19
)
,
C
[
4
]
=
C
[
4
]
−
C
[
5
]
{\displaystyle C[5]=C[5]\oplus C[4],\ \ C[5]={\text{ROR}}(C[5],19),\ \ C[4]=C[4]-C[5]}
C
[
3
]
=
C
[
3
]
⊕
C
[
2
]
,
C
[
3
]
=
ROR
(
C
[
3
]
,
36
)
,
C
[
2
]
=
C
[
2
]
−
C
[
3
]
{\displaystyle C[3]=C[3]\oplus C[2],\ \ C[3]={\text{ROR}}(C[3],36),\ \ C[2]=C[2]-C[3]}
C
[
1
]
=
C
[
1
]
⊕
C
[
0
]
,
C
[
1
]
=
ROR
(
C
[
1
]
,
46
)
,
C
[
0
]
=
C
[
0
]
−
C
[
1
]
{\displaystyle C[1]=C[1]\oplus C[0],\ \ C[1]={\text{ROR}}(C[1],46),\ \ C[0]=C[0]-C[1]}
}
{\displaystyle \}}
C
[
6
]
=
C
[
6
]
−
T
[
1
]
{\displaystyle C[6]=C[6]-T[1]}
C
[
5
]
=
C
[
5
]
−
T
[
0
]
{\displaystyle C[5]=C[5]-T[0]}
For
i
=
0
to
7
do
P
[
i
]
=
C
[
i
]
−
K
[
i
]
{\displaystyle {\text{For }}i=0{\text{ to }}7{\text{ do }}P[i]=C[i]-K[i]}
Return
P
{\displaystyle {\text{Return }}P}
ראו גם
הערות שוליים
בעיות מתמטיות ואלגוריתמים
31030087 Threefish