お茶の時間です!


8

前書き

しばらく前に私は小さな暗号化アルゴリズムTEA)を偶然見つけました。それ以来、特別な暗号化セキュリティプロパティが不要で、自己実装が要件であるときはいつでもそれを勧めてきました。
今日は、* tiny *暗号化アルゴリズムという名前を文字通り使用したいと思います。あなたの仕事は、最も小さな暗号化アルゴリズムを実装することです!

仕様

入力

入力は8バイト(または同等の言語)のリストであり、これは平文であり、16バイト(または同等の言語)の別のリストであり、これはkeyです。
10進数、16進数、8進数、または2進数からの入力変換が可能です。
1 64ビット、2 32ビットまたは4 16ビット整数を出力として(オプションでリストとして)読み取ることができます(プレーンテキストの場合、キーの数値を2倍にします)

出力

出力は8バイト(または同等の言語)のリストで、これは暗号文です。
10進数、16進数、8進数、または2進数への出力変換は許可されていますが、必須ではありません。
出力として1 64ビット、2 32ビット、または4 16ビット整数を(オプションでリストとして)書き込むことができます。

何をすべきか?

あなたの仕事は実装することである暗号化方向の小さな暗号化アルゴリズム(のTEA)、ノートXTEAとXXTEAが他のアルゴリズムです。
ウィキペディアには、Cコードの例と、他の言語でのいくつかの実装への参照のリストがあります。これは元の説明(PDF)です。

より正式に:

Let k1, k2, k3, k4, v1, v2, sum be unsigned 32-bit integers.
(k1,k2,k3,k4) <- key input
(v1,v2) <- plaintext input
sum <- 0
repeat 32 times:
    sum <- ( sum + 0x9e3779b9 ) mod 2^32
    v0  <- ( v0 + ( ((v1 << 4) + k0) XOR (v1 + sum) XOR ((v1 >> 5) + k1) ) ) mod 2^32
    v1  <- ( v1 + ( ((v0 << 4) + k2) XOR (v0 + sum) XOR ((v0 >> 5) + k3) ) ) mod 2^32
output <- (v0,v1)

where 0x9e3779b9 is a hexadecimal constant and
"<<" denotes logical left shift and ">>" denotes logical right shift.

潜在的なコーナーケース

\0 は有効な文字であり、入力または出力を短くすることはできません。
整数エンコーディングはリトルエンディアン(たとえば、おそらくすでに持っているもの)であると想定されます。

誰が勝ちますか?

これはコードゴルフなので、バイト単位の最も短い答えが勝ちます!
もちろん標準的なルールが適用されます。

テストケース

テストベクタは、Wikipedia Cのコード例を使用して生成されました。

Key: all zero (16x \0)
Plaintext -> Ciphertext (all values as two 32-bit hexadecimal words)
00000000 00000000 -> 41ea3a0a 94baa940
3778001e 2bf2226f -> 96269d3e 82680480
48da9c6a fbcbe120 -> 2cc31f2e 228ad143
9bf3ceb8 1e076ffd -> 4931fc15 22550a01
ac6dd615 9c593455 -> 392eabb4 505e0755
ebad4b59 7b962f3c -> b0dbe165 cfdba177
ca2d9099 a18d3188 -> d4641d84 a4bccce6
b495318a 23a1d131 -> 39f73ca0 bda2d96c
bd7ce8da b69267bf -> e80efb71 84336af3
235eaa32 c670cdcf -> 80e59ecd 6944f065
762f9c23 f767ea2c -> 3f370ca2 23def34c

以下は、ゼロ以外のキーを持ついくつかの自己生成テストベクトルです。

format: ( 4x 32-bit word key , 2x 32-bit word plaintext ) -> ( 2x 32-bit word ciphertext )
(all in hexadecimal)

( 4300e123 e39877ae 7c4d7a3c 98335923 , a9afc671 79dcdb73 ) -> ( 5d357799 2ac30c80 )
( 4332fe8f 3a127ee4 a9ca9de9 dad404ad , d1fe145a c84694ee ) -> ( a70b1d53 e7a9c00e )
( 7f62ac9b 2a0771f4 647db7f8 62619859 , 618f1ac2 67c3e795 ) -> ( 0780b34d 2ca7d378 )
( 0462183a ce7edfc6 27abbd9a a634d96e , 887a585d a3f83ef2 ) -> ( d246366c 81b87462 )
( 34c7b65d 78aa9068 599d1582 c42b7e33 , 4e81fa1b 3d22ecd8 ) -> ( 9d5ecc3b 947fa620 )
( f36c977a 0606b8a0 9e3fe947 6e46237b , 5d8e0fbe 2d3b259a ) -> ( f974c6b3 67e2decf )
( cd4b3820 b2f1e5a2 485dc7b3 843690d0 , 48db41bb 5ad77d7a ) -> ( b4add44a 0c401e70 )
( ee2744ac ef5f53ec 7dab871d d58b3f70 , 70c94e92 802f6c66 ) -> ( 61e14e3f 89408981 )
( 58fda015 c4ce0afb 49c71f9c 7e0a16f0 , 6ecdfbfa a705a912 ) -> ( 8c2a9f0c 2f56c18e )
( 87132255 41623986 bcc3fb61 7e6142ce , 9d0eff09 55ac6631 ) -> ( 8919ea55 c7d430c6 )

1
ウィキペディアのCコードを試したところ、ゼロキーと平文を使用して、平文の2行目を暗号文として取得しました...
Neil

さて、最初の2つは今やります。でも私は怠惰すぎて残りを試すことができません。
Neil

@ニール、それが暗号のいいところです:確率が高く、取るに足らない(0ベース)とそうでないテストベクターが合格した場合、すべてのテストベクターが合格します:)
SEJPM

2
ゼロ以外のキーを使用していくつかのテストケースを追加することをお勧めします。
Dennis

@Dennisそれらは質問の最後にあります:)
SEJPM 2016年

回答:


5

JavaScriptの(ES6)、122の 118 114 113バイト

f=
(v,w,k,l,m,n)=>{for(s=0;s<84e9;v+=w*16+k^w+s^(w>>>5)+l,w+=v*16+m^v+s^(v>>>5)+n)s+=0x9e3779b9;return[v>>>0,w>>>0]}
;
<div oninput="[r0.value,r1.value]=f(...[v0,v1,k0,k1,k2,k3].map(i=>parseInt(i.value,16))).map(i=>(i+(1<<30)*4).toString(16).slice(1))">
Plain 0: <input id=v0><br>
Plain 1: <input id=v1><br>
Key 0: <input id=k0><br>
Key 1: <input id=k1><br>
Key 2: <input id=k2><br>
Key 3: <input id=k3><br>
</div>
Cipher 0: <input id=r0 readonly><br>
Cipher 1: <input id=r1 readonly><br>

注:リトルエンディアン演算を使用します。符号なし32ビット整数値を受け入れて返します。編集:左シフトの代わりに乗算を使用して4バイトを節約しました。テストを行うことで4バイトを節約しs、個別のループ変数を回避しました。+=内でを移動することにより、1バイトを節約しましたfor


returnではなく、暗黙のreturnでevalを使用しないのはなぜですか?
Downgoat

交換{return}では、eval('')私にどんなバイトを保存しません
ニール・

大丈夫。それは数バイトを節約すると思いました:(
Downgoat

4

ルビー、114の 113 106バイト

Rubyには32ビット演算機能がないため、追加のmod操作により、Rubyの他のバイト節約操作にもかかわらずJavascript とほぼ連携していました...

  • (余分なセミコロンから1バイト)
  • (不必要なmod操作のトリミングとシフトから-7バイト)

オンラインでお試しください!

->v,w,a,b,c,d{s=0
32.times{s+=0x9e3779b9;v+=w*16+a^w+s^w/32+b;v%=m=2**32;w+=v*16+c^v+s^v/32+d;w%=m}
[v,w]}

2

C、116バイト

T(v,w,k,l,m,n,s)unsigned*v,*w;{for(s=0;s+957401312;*v+=*w*16+k^*w+s^*w/32+l,*w+=*v*16+m^*v+s^*v/32+n)s+=2654435769;}

平文をvおよびwとして受け取ります。klm、およびnとしてのキー。暗号文をvおよびwに格納します。

Ideoneでテストします。


2

J、149バイト

4 :0
'u v'=.y
s=.0
m=.2x^32
for.i.32
do.s=.m|s+2654435769
u=.m|u+(22 b.)/(s+v),(2{.x)+4 _5(33 b.)v
v=.m|v+(22 b.)/(s+u),(2}.x)+4 _5(33 b.)u
end.u,v
)

わーい!明示的(ブー!)J!これを暗黙のうちに行う方法はあると思いますが、おそらく読めなくなるでしょう。

使用法

キーをLHSでは4つの32ビット整数として、プレーンテキストではRHSで2つの32ビット整数として受け取ります。プレフィックス16b0x他の言語と同等で、16進値を表します。組み込みhfdは、テストを簡単にするために出力を16進文字列にフォーマットします。

    f =: 4 :0
'u v'=.y
s=.0
m=.2x^32
for.i.32
do.s=.m|s+2654435769
u=.m|u+(22 b.)/(s+v),(2{.x)+4 _5(33 b.)v
v=.m|v+(22 b.)/(s+u),(2}.x)+4 _5(33 b.)u
end.u,v
)
   hfd 0 0 0 0 f 0 0
41ea3a0a
94baa940
   hfd 0 0 0 0 f 16b3778001e 16b2bf2226f
96269d3e
82680480
   hfd 16b4300e123 16be39877ae 16b7c4d7a3c 16b98335923 f 16ba9afc671 16b79dcdb73 
5d357799
2ac30c80
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.