이 과제의 목표는 사용자가 선택한 언어로 다음 기능을 구현할 수 없을 정도로 짧은 구현 을 찾는 것입니다 p
. 여기에 그것을 구현하는 C 코드 ( 출력을 인쇄하는 TIO 링크 참조
)와 그것을 포함 하는 wikipedia 페이지 가 있습니다.
unsigned char pi[] = {
252,238,221,17,207,110,49,22,251,196,250,218,35,197,4,77,
233,119,240,219,147,46,153,186,23,54,241,187,20,205,95,193,
249,24,101,90,226,92,239,33,129,28,60,66,139,1,142,79,
5,132,2,174,227,106,143,160,6,11,237,152,127,212,211,31,
235,52,44,81,234,200,72,171,242,42,104,162,253,58,206,204,
181,112,14,86,8,12,118,18,191,114,19,71,156,183,93,135,
21,161,150,41,16,123,154,199,243,145,120,111,157,158,178,177,
50,117,25,61,255,53,138,126,109,84,198,128,195,189,13,87,
223,245,36,169,62,168,67,201,215,121,214,246,124,34,185,3,
224,15,236,222,122,148,176,188,220,232,40,80,78,51,10,74,
167,151,96,115,30,0,98,68,26,184,56,130,100,159,38,65,
173,69,70,146,39,94,85,47,140,163,165,125,105,213,149,59,
7,88,179,64,134,172,29,247,48,55,107,228,136,217,231,137,
225,27,131,73,76,63,248,254,141,83,170,144,202,216,133,97,
32,113,103,164,45,43,9,91,203,155,37,208,190,229,108,82,
89,166,116,210,230,244,180,192,209,102,175,194,57,75,99,182,
};
unsigned char p(unsigned char x) {
return pi[x];
}
뭐가 p
p
두 개의 러시아 암호화 표준, 즉 해시 함수 Streebog 및 블록 암호 Kuznyechik 의 구성 요소입니다 . 에서 이 문서 (및 ISO 회의 중), 이러한 알고리즘의 디자이너들은 배열을 생성 주장 pi
임의의 8 비트 순열을 선택하여.
"불가능한"구현
이 있습니다8 비트에서 순열. 따라서, 임의의 순열에 대해,이를 구현하는 프로그램은 1683 비트 미만을 필요로하지 않아야한다.
그러나 다음과 같은 C 프로그램과 같이 비정상적으로 작은 구현이 여러 개 발견되었습니다 ( 여기에 나열 됨 ).
p(x){unsigned char*k="@`rFTDVbpPBvdtfR@\xacp?\xe2>4\xa6\xe9{z\xe3q5\xa7\xe8",l=0,b=17;while(--l&&x^1)x=2*x^x/128*285;return l%b?k[l%b]^k[b+l/b]^b:k[l/b]^188;}
158 자만 포함하므로 1264 비트에 맞습니다. 작동하는지 확인 하려면 여기 를 클릭하십시오 .
순열이 임의 프로세스의 출력 (디자이너가 주장한대로) 인 경우이 짧은 프로그램이 존재하지 않기 때문에 "불가능하게"짧은 구현에 대해 이야기합니다 ( 자세한 내용 은 이 페이지 참조).
참조 구현
이전 C 코드의 더 읽기 쉬운 버전은 다음과 같습니다.
unsigned char p(unsigned char x){
unsigned char
s[]={1,221,146,79,147,153,11,68,214,215,78,220,152,10,69},
k[]={0,32,50,6,20,4,22,34,48,16,2,54,36,52,38,18,0};
if(x != 0) {
unsigned char l=1, a=2;
while(a!=x) {
a=(a<<1)^(a>>7)*29;
l++;
}
unsigned char i = l % 17, j = l / 17;
if (i != 0) return 252^k[i]^s[j];
else return 252^k[j];
}
else return 252;
}
표 k
는 C에서와 같이 XOR을 나타내는 의미에서 선형 k[x] = L(16-x)
인 위치 L
에 있습니다. 그러나 구현을 단축하기 위해이 속성을 활용하지 못했습니다. 우리는 더 간단한 구현을 허용하는 구조를 알지 못합니다. 출력은 항상 서브 필드에 있습니다. 즉 유한 필드에서 지수가 수행되는 입니다. 물론, 당신은 당신이 하나를 발견하면 더 간단한 표현을 사용할 수 있습니다!L(x^y)==L(x)^L(y)
^
s
s
while 루프는 256 개의 요소가있는 유한 필드의 이산 로그 평가에 해당합니다. 단순 무차별 검색을 통해 작동합니다. 더미 변수 a
는 유한 필드의 생성자로 설정되고 결과가 같을 때까지이 생성기에 곱합니다 x
. 이 경우, 우리는 l
이산 로그를가 x
집니다. 이 함수는 0에 정의되어 있지 않으므로 if
명령문에 해당하는 특수한 경우 입니다.
제너레이터에 의한 곱셈 은 에서 에 의한 곱셈으로 볼 수 있으며 , 다항식 은 모듈로 감소 됩니다. 의 역할은 변수 가 8 비트로 유지 되도록하는 것 입니다. 또한, 우리가 사용할 수 있는 경우는, 수 (또는 다른 정수형). 다른 한편으로, 우리가 1과 같을 때 필요한만큼 시작 해야합니다 .unsigned char
a
a=(a<<1)^(a>>7)*(256^29)
a
int
l=1,a=2
l=255
x
의 속성에 대한 자세한 내용은 p
에 제시되어 우리의 종이 이전의 짧은 구현을 얻을 수 있도록 최적화 대부분의 작성자와.
규칙
p
1683 비트 미만으로 기능을 구현하는 프로그램을 제안하십시오 . 프로그램이 짧을수록 주어진 언어에 대해 비정상 일수록 짧을수록 좋습니다. 귀하의 언어에 Kuznyechik, Streebog 또는 p
내장 언어가있는 경우 해당 언어를 사용할 수 없습니다.
최상의 구현을 결정하기 위해 사용하는 메트릭은 바이트 단위의 프로그램 길이입니다. 우리는 학술 논문에서 비트 길이를 사용하지만 단순성을 위해 여기에 바이트를 사용합니다.
언어에 함수, 인수 또는 출력에 대한 명확한 개념이없는 경우 인코딩은 사용자가 정의해야하지만 값 pi[x]
을 x
분명히 인코딩하는 것과 같은 트릭 은 금지되어 있습니다.
우리는 이미이 주제에 대한 연구 결과를 포함한 연구 논문을 제출했습니다. 그것은 사용할 수 있습니다 여기에 . 그러나 과학적인 장소에 게시되면 최고의 구현을 만든 작가에게 기꺼이 인정할 것입니다.
그건 그렇고,이 질문을 작성할 때 도움을 주신 xnor에게 감사드립니다!
1683 bits at most
엄격한 제한 [sic?]입니까 아니면 목표입니까?