मैं गिमली के लेखकों में से एक हूं। हमारे पास पहले से ही C में 2-ट्वीट (280 वर्ण) संस्करण है, लेकिन मैं देखना चाहता हूं कि यह कितना छोटा हो सकता है।
Gimli ( पेपर , वेबसाइट ) उच्च सुरक्षा स्तर के क्रिप्टोग्राफ़िक क्रमांकन डिज़ाइन के साथ एक उच्च गति है जिसे क्रिप्टोग्राफ़िक हार्डवेयर और एंबेडेड सिस्टम (CHES) 2017 (25-28 सितंबर ) पर सम्मेलन में प्रस्तुत किया जाएगा ।
काम
हमेशा की तरह: अपनी पसंद की भाषा में गिम्ली के छोटे प्रयोग को लागू करने के लिए।
यह इनपुट 384 बिट्स (या 48 बाइट्स, या 12 अहस्ताक्षरित int ...) के रूप में लेने में सक्षम होना चाहिए और वापस लौटाना (यदि आप पॉइंटर्स का उपयोग करते हैं तो संशोधित कर सकते हैं) इन 384 बिट्स पर लागू Gimli का परिणाम है ।
दशमलव, हेक्साडेसिमल, ऑक्टल या बाइनरी से इनपुट रूपांतरण की अनुमति है।
संभावित कोने के मामले
पूर्णांक एन्कोडिंग को अल्प-एंडियन माना जाता है (उदाहरण के लिए आपके पास पहले से क्या है)।
आप का नाम बदलने सकता है Gimli
मेंG
लेकिन यह अभी भी एक समारोह कॉल किया जाना चाहिए।
किसी जीत?
यह कोड-गोल्फ है इसलिए बाइट्स जीत में सबसे छोटा जवाब है! मानक नियम निश्चित रूप से लागू होते हैं।
एक संदर्भ कार्यान्वयन नीचे दिया गया है।
ध्यान दें
कुछ चिंता जताई गई है:
"हे गिरोह, कृपया मेरे कार्यक्रम को अन्य भाषाओं में मुफ्त में लागू करें ताकि मुझे" (thx to @jstnthms) नहीं करना पड़े।
मेरा उत्तर इस प्रकार है:
मैं इसे आसानी से जावा, सी #, जेएस, ओक्लेमल में कर सकता हूं ... यह मजाक के लिए अधिक है। वर्तमान में हम (Gimli टीम) ने AVR, Cortex-M0, Cortex-M3 / M4, नियॉन, SSE, SSE-unrolled, AVX, AVX2, VHL और पायथन 3 पर इसे लागू (और अनुकूलित) किया है। :)
गिमली के बारे में
राज्य
Gimli 384-बिट अवस्था में राउंड के अनुक्रम को लागू करता है। राज्य को 3 × 4 × 32 या, समान रूप से, 32-बिट शब्दों के 3 × 4 मैट्रिक्स के रूप में आयामों के साथ एक समानांतर चतुर्भुज के रूप में दर्शाया गया है।
प्रत्येक दौर में तीन ऑपरेशनों का क्रम होता है:
- एक गैर-रैखिक परत, विशेष रूप से प्रत्येक स्तंभ पर लागू 96-बिट एसपी-बॉक्स;
- हर दूसरे दौर में, एक रैखिक मिश्रण परत;
- हर चौथे दौर में, एक निरंतर जोड़।
गैर-रैखिक परत।
एसपी-बॉक्स में तीन उप-संचालन होते हैं: पहले और दूसरे शब्दों के रोटेशन; एक 3-इनपुट nonlinear टी-फ़ंक्शन; और पहले और तीसरे शब्द की अदला-बदली।
रैखिक परत।
लीनियर परत में दो स्वैप ऑपरेशन होते हैं, जिनका नाम स्मॉल-स्वैप और बिग-स्वैप है। स्मॉल-स्वैप हर 4 राउंड में होता है जो 1 राउंड से शुरू होता है। 3-राउंड से शुरू होने वाले हर 4 राउंड में बिग-स्वैप होता है।
दौर लगातार।
गिम्ली में 24 राउंड हैं, जिनकी संख्या 24,23, ..., 1 है। जब गोल संख्या r 24,20,16,12,8,4 है तो हम पहले राज्य शब्द के लिए गोल स्थिरांक (0x9e377900 XOR r) को XOR करते हैं।
C में संदर्भ स्रोत
#include <stdint.h>
uint32_t rotate(uint32_t x, int bits)
{
if (bits == 0) return x;
return (x << bits) | (x >> (32 - bits));
}
extern void gimli(uint32_t *state)
{
int round;
int column;
uint32_t x;
uint32_t y;
uint32_t z;
for (round = 24; round > 0; --round)
{
for (column = 0; column < 4; ++column)
{
x = rotate(state[ column], 24);
y = rotate(state[4 + column], 9);
z = state[8 + column];
state[8 + column] = x ^ (z << 1) ^ ((y&z) << 2);
state[4 + column] = y ^ x ^ ((x|z) << 1);
state[column] = z ^ y ^ ((x&y) << 3);
}
if ((round & 3) == 0) { // small swap: pattern s...s...s... etc.
x = state[0];
state[0] = state[1];
state[1] = x;
x = state[2];
state[2] = state[3];
state[3] = x;
}
if ((round & 3) == 2) { // big swap: pattern ..S...S...S. etc.
x = state[0];
state[0] = state[2];
state[2] = x;
x = state[1];
state[1] = state[3];
state[3] = x;
}
if ((round & 3) == 0) { // add constant: pattern c...c...c... etc.
state[0] ^= (0x9e377900 | round);
}
}
}
सी में ट्वीट करने योग्य संस्करण
यह सबसे छोटा प्रयोग करने योग्य कार्यान्वयन नहीं हो सकता है लेकिन हम एक सी मानक संस्करण (इस प्रकार कोई यूबी, और एक पुस्तकालय में "प्रयोग करने योग्य") नहीं चाहते थे।
#include<stdint.h>
#define P(V,W)x=V,V=W,W=x
void gimli(uint32_t*S){for(long r=24,c,x,y,z;r;--r%2?P(*S,S[1+y/2]),P(S[3],S[2-y/2]):0,*S^=y?0:0x9e377901+r)for(c=4;c--;y=r%4)x=S[c]<<24|S[c]>>8,y=S[c+4]<<9|S[c+4]>>23,z=S[c+8],S[c]=z^y^8*(x&y),S[c+4]=y^x^2*(x|z),S[c+8]=x^2*z^4*(y&z);}
टेस्ट वेक्टर
निम्न इनपुट द्वारा उत्पन्न
for (i = 0;i < 12;++i) x[i] = i * i * i + i * 0x9e3779b9;
और "मुद्रित" मूल्यों द्वारा
for (i = 0;i < 12;++i) {
printf("%08x ",x[i])
if (i % 4 == 3) printf("\n");
}
इस प्रकार:
00000000 9e3779ba 3c6ef37a daa66d46
78dde724 1715611a b54cdb2e 53845566
f1bbcfc8 8ff34a5a 2e2ac522 cc624026
लौटना चाहिए:
ba11c85a 91bad119 380ce880 d24c2c68
3eceffea 277a921c 4f73a0bd da5a9cd8
84b673f0 34e52ff7 9e2bef49 f41bb8d6
-round
बजाय --round
का मतलब है कि यह कभी नहीं समाप्त हो जाता है। --
एन डैश पर कनवर्ट करने का सुझाव शायद कोड में नहीं दिया गया है :)