Gimli, इसे और भी छोटा कर दें?


25

मैं गिमली के लेखकों में से एक हूं। हमारे पास पहले से ही 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 

3
एक ट्वीट 140 चांस है, न कि 280
स्टेन स्ट्रम

1
मुझे पता है, यही कारण है कि यह 2 में फिट बैठता है;) twitter.com/TweetGimli
बीवी

10
"हे गिरोह, कृपया मेरे कार्यक्रम को अन्य भाषाओं में मुफ्त में लागू करें ताकि मुझे" "नहीं करना है
jstnthms

हाहा नाह मेरे पास पहले से ही पायथन में है, और मैं इसे आसानी से जावा, सी #, जेएस में कर सकता हूं। यह मनोरंजन के लिए अधिक है। :)
बीवी

5
संदर्भ कोड वेबसाइट पर एक महत्वपूर्ण त्रुटि है, -roundबजाय --roundका मतलब है कि यह कभी नहीं समाप्त हो जाता है। --एन डैश पर कनवर्ट करने का सुझाव शायद कोड में नहीं दिया गया है :)
orlp

जवाबों:


3

सीजाम (114 वर्ण)

{24{[4/z{[8ZT].{8\#*G8#:Mmd+}__)2*\+.^W%\[_~;&8*\~@1$|2*@@&4*].^Mf%}%z([7TGT]R=4e!=\f=(2654435608R-_4%!*^\@]e_}fR}

यह एक अनाम ब्लॉक (फ़ंक्शन) है: यदि आप इसे नाम देना चाहते हैं Gतो संलग्न करें :G। सीजेएम में सौंपे गए नामों में केवल ऊपरी मामले वाले पत्र ही हो सकते हैं। एक टिप्पणी को जोड़ने e# Gimli in CJamऔर एक ही ट्वीट में पात्रों को छोड़ने के लिए जगह है।

ऑनलाइन टेस्ट

विच्छेदन

{                                e# Define a block
  24{                            e# For R=0 to 23...
    [                            e#   Collect values in an array
      4/z                        e#     Transpose to columns
      {                          e#     Map over each column
        [8ZT].{8\#*G8#:Mmd+}     e#       Rotations, giving [x y z]
        __)2*\+.^W%\             e#       => [y^z x^y x^z*2] [x y z]
        [_~;&8*\~@1$|2*@@&4*].^  e#       => [x' y' z']
        Mf%                      e#       Map out any bits which overflowed
      }%
      z                          e#    Transpose to rows
      ([7TGT]R=4e!=\f=           e#    Permute first row
      (2654435608R-_4%!*^        e#    Apply round constant to first element
      \@                         e#    Put the parts in the right order
    ]e_                          e#  Finish collecting in array and flatten
  }fR
}

एक पल के लिए मुझे इस तथ्य से फेंक दिया गया कि ओपुत हेक्स में नहीं था (ऑनलाइन परीक्षण में)। :)
बीवी

15

सी (जीसीसी), 237 बाइट्स

#define P(a,l)x=a;a=S[c=l>>r%4*2&3];S[c]=x;
r,c,x,y,z;G(unsigned*S){
for(r=24;r;*S^=r--%4?0:0x9e377901+r){
for(c=4;c--;*S++=z^y^8*(x&y))
x=*S<<24|*S>>8,y=S[4]<<9|S[4]>>23,z=S[8],S[8]=x^2*z^4*(y&z),S[4]=y^x^2*(x|z);
S-=4;P(*S,33)P(S[3],222)}}

मैं शायद अपने गमागमन विधि के साथ बाइट्स प्राप्त किया है, लेकिन यह बहुत प्यारा है उपयोग करने के लिए नहीं।


खो दिया या प्राप्त किया?
हाइपरएन्यूट्रीनो

@ हेपर न्युट्रीनो, मुझे हारने वाला बना :)
orlp

आह ठीक है: P समझ में आता है: P: P
HyperNeutrino

यह अभी भी निश्चित रूप से एक सुधार है, लेकिन यह (और ओपी कोड का उपयोग करने के लिए कुछ धोखा दे रहा था ) के unsignedबजाय उपयोग करने के uint32_tलिए कुछ धोखा है longक्योंकि सिफर के पीछे का विचार यह है कि यह अत्यधिक पोर्टेबल है। (वास्तव में, मौलिक रूप से यह केवल 8 बाइट्स बचाता है)।
पीटर टेलर

1
@PeterTaylor भले ही मेरा कोड समान है, लेकिन मैं वास्तव में ओपी के कोड के खिलाफ प्रतिस्पर्धा नहीं कर रहा हूं। मैं पीपीसीजी के नियमों के तहत काम कर रहा हूं, जहां इसे कम से कम एक प्लेटफॉर्म पर कार्यान्वयन के साथ काम करना होगा, और यह gcc32-बिट या 64-बिट इंटेल सीपीयू (और शायद बहुत अधिक) पर करता है।
orlp

4

सी, 268 चार्ट (268 बाइट्स) uint32_t का उपयोग कर

NB चूंकि मूल कोड का उपयोग करता है <stdint.h>और प्रकार के Sरूप में uint32_t *, मुझे लगता longहै कि पोर्टेबिलिटी की कीमत पर 280 चार्ट में जाने के लिए एक धोखा है जो uint32_tपहली जगह में उपयोग करने का कारण है। यदि तुलना की निष्पक्षता के लिए हमें निरंतर उपयोग uint32_tऔर स्पष्ट हस्ताक्षर की आवश्यकता होती है void gimli(uint32_t *), तो मूल कोड वास्तव में 284 वर्ण है, और orlp का कोड 276 वर्ण है।

#include<stdint.h>
#define R(V)x=S[V],S[V]=S[V^y],S[V^y]=x,
void gimli(uint32_t*S){for(uint32_t r=24,x,y,z,*T;r--;y=72>>r%4*2&3,R(0)R(3)*S^=y&1?0x9e377901+r:0)for(T=S+4;T-->S;*T=z^y^8*(x&y),T[4]=y^x^2*(x|z),T[8]=x^2*z^4*(y&z))x=*T<<24|*T>>8,y=T[4]<<9|T[4]>>23,z=T[8];}

इसे निरंतर रूप से चिह्नित मार्करों के साथ दो ट्वीट्स में विभाजित किया जा सकता है

#include<stdint.h>
#define R(V)x=S[V],S[V]=S[V^y],S[V^y]=x,
void gimli(uint32_t*S){for(uint32_t r=24,x,y,z,*T;r--;y=72>>r%4*2&3,R(0)R(3)// 1

तथा

*S^=y&1?0x9e377901+r:0)for(T=S+4;T-->S;*T=z^y^8*(x&y),T[4]=y^x^2*(x|z),T[8]=x^2*z^4*(y&z))x=*T<<24|*T>>8,y=T[4]<<9|T[4]>>23,z=T[8];}// 2/2

के उपयोग longमें मेरी संस्करण सुरक्षित (पोर्टेबिलिटी के संबंध में), क्योंकि एक लंबे का न्यूनतम आकार मानक से 32 बिट (के रूप में करने का विरोध किया है int)। के रोटेशन xऔर yमें डाली से पहले किया जाता है longकाम पर, उन्हें सुरक्षित बनाने (के रूप में हस्ताक्षर किए मूल्य पर सही पारी सीसी निर्भर है)। कास्ट जब वापस जा रहा है uint32_t* S) ऊपरी बिट्स से छुटकारा पाता है और हमें सही स्थिति में डालता है :)।
बीवी

2

जावा (ओपनजेडके 8) , 351 343 339 320 318 247 + 56 बाइट्स

गोल्फिंग शुरू करने के लिए संदर्भ के सिर्फ 1: 1 बंदरगाह के पास।

void f(int[]x,int y,int z){int q=x[y];x[y]=x[z];x[z]=q;}

s->{for(int r=24,c,x,y,z;r>0;--r){for(c=0;c<4;x=s[c]<<24|s[c]>>>8,y=s[4+c]<<9|s[4+c]>>>23,z=s[8+c],s[8+c]=x^z<<1^(y&z)<<2,s[4+c]=y^x^(x|z)<<1,s[c++]=z^y^(x&y)<<3);if((r&3)==2){f(s,0,2);f(s,1,3);}if((r&3)<1){f(s,0,1);f(s,2,3);s[0]^=0x9e377900|r;}}}

इसे ऑनलाइन आज़माएं!


1
आखिर क्यों इस्तेमाल करें Integer? o_O चूंकि आप किसी भी Integerविधि का उपयोग नहीं करते हैं , इसलिए एस का उपयोग न करने का कोई कारण नहीं intहै ...
ओलिवियर ग्राईगोइयर

@ OlivierGrégoire मुझे लगता है कि मेरे पास बस एक अवशेष है जो Integer.divideUnsign की कोशिश कर रहा है, लेकिन मुझे एहसास हुआ कि मैं >>>
रॉबर्टो ग्राहम

s[0]^=(0x9e377900|r);(बहुत अंत में) - क्या आप अतिरिक्त कोष्ठक नहीं छोड़ सकते?
क्लैशॉफ्ट

उसी के साथ s[4+c]>>>(23)
क्लैशसॉफ्ट

1
आप अब तक कम परिवर्तन करते हैं और 300 प्राप्त कर सकते हैं: void P(int[]S,int a,int b){int x=S[a];S[a]=S[b];S[b]=x;}void gimli(int[]S){for(int r=24,c,x,y,z;r>0;S[0]^=y<1?0x9e377901+r:0){for(c=4;c-->0;){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);}y=r%4;if(--r%2>0){P(S,0,1+y/2);P(S,3,2-y/2);}}}। मैंने मूल रूप से इसे संकलित करने के लिए आवश्यक न्यूनतम बदलाव किए हैं। जावा की पूर्ववर्ती नियम C के लिए बहुत भिन्न नहीं हैं।
पीटर टेलर

2

जावास्क्रिप्ट (ईएस 6), 231 बाइट्स

s=>{for(r=25;--r;[a,b,c,d,...e]=s,s=r&1?s:r&2?[c,d,a,b,...e]:[b,a,d,c,...e],s[0]^=r&3?0:0x9e377900|r)for(c=4;c--;x=s[c]<<24|s[c]>>>8,y=s[j=c+4]<<9|s[j]>>>23,z=s[c+8],s[c+8]=x^z*2^(y&z)*4,s[j]=y^x^(x|z)*2,s[c]=z^y^(x&y)*8);return s}

डेमो


0

32-बिट x86 कोडांतरक (112 बाइट्स)

(__cdecl कॉलिंग कन्वेंशन)

            pusha
            mov     ecx, 9E377918h
    loc_6:  mov     esi, [esp+24h]
            push    esi
            push    4
            pop     ebx
    loc_E:  lodsd
            ror     eax, 8
            mov     ebp, [esi+0Ch]
            rol     ebp, 9
            mov     edx, [esi+1Ch]
            push    eax
            push    ebp
            lea     edi, [edx+edx]
            and     ebp, edx
            shl     ebp, 2
            xor     edi, ebp
            xor     eax, edi
            mov     [esi+1Ch], eax
            pop     ebp
            pop     eax
            push    eax
            push    ebp
            xor     ebp, eax
            or      eax, edx
            shl     eax, 1
            xor     ebp, eax
            mov     [esi+0Ch], ebp
            pop     ebp
            pop     eax
            xor     edx, ebp
            and     eax, ebp
            shl     eax, 3
            xor     edx, eax
            push    edx
            dec     ebx
            jnz     short loc_E
            pop     esi
            pop     ebp
            pop     ebx
            pop     eax
            pop     edi
            mov     dl, cl
            and     dl, 3
            jnz     short loc_5B
            xchg    eax, ebx
            xchg    esi, ebp
            xor     eax, ecx
    loc_5B: cmp     dl, 2
            jnz     short loc_63
            xchg    eax, ebp
            xchg    esi, ebx
    loc_63: stosd
            xchg    eax, ebx
            stosd
            xchg    eax, ebp
            stosd
            xchg    eax, esi
            stosd
            dec     cl
            jnz     short loc_6
            popa
            retn

ट्वीट करने योग्य संस्करण (z85-format Base85 एन्कोडिंग):

v7vb1h> सी} HbQuA91y51A: oWYw48G) मैं = एच /] rGf9Na> sA.DWu06 {6F # टीईसी ^ मुख्यमंत्री: # आईईए-cstx7:!> VfVf # यू * वाई बी और सांसद (tuCl * + 7eENBP) $ :) Lh कश्मीर } टी $ ^ wM51j% एलडीएफ $ HMAg2bB ^ MQP
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.