2013-08-25 2 views
1

로그와 지수 테이블을 사용하여 GF (2^8)에서 곱셈과 나눗셈을 구현하려고합니다. here의 지침을 사용하여 3의 지수를 제네레이터로 사용하고 있습니다.갈루아 필드 (2^8)의 잘못된 곱셈/나눗셈

그러나 나는 사소한 테스트 케이스에 실패하고 있습니다.

예 : 첫 번째 4 개 개의 라인이 통과

//passes 
assert((GF256elm(4)/GF256elm(1)) == GF256elm(4)); 
assert((GF256elm(32)/GF256elm(16)) == GF256elm(2)); 
assert((GF256elm(15)/GF256elm(5)) == GF256elm(3)); 
assert((GF256elm(88)/GF256elm(8)) == GF256elm(11)); 
//fails, but should pass 
assert((GF256elm(77)/GF256elm(11)) == GF256elm(7)); 
assert((GF256elm(77)/GF256elm(7)) == GF256elm(11)); 

그러나 그것은 5, 6 라인 모두에서 실패합니다.
추가 조사를 통해 이러한 오류가 '랩 어라운드'(예 : log3(a) + log3(b) > 255 (곱하기)) 또는 log3(a) - log3(b) < 0 일 때 발생한다는 것을 알았습니다. 그러나 값은 실제 모듈러스를 사용하여 0 ~ 255로 유지되는 "modded"입니다.

GF256elm& GF256elm::operator/=(const GF256elm& other) { //C++ operator override for division 
    int t = _logTable[val] - _logTable[other.val]; //log3(a) - log3(b) 
    int temp = ((t % 255) + 255) % 255; //this wraps the value to between 0~254 inclusive. 
    val = _expTable[temp]; 
    return *this; 
} 

/ 연산자는 특별한 아무것도 일어나지 않습니다 위의 /= 재정의를 사용하여 구현됩니다.

생성 된 log/exp 테이블이 올바른지 확인했습니다.

무엇이 여기에 있습니까? 감사!

+0

사과드립니다. 예, 구현했습니다. 언급 했어야합니다. 기본적으로 LHS와 RHS 조건에서'/ ='를 사용하고 결과를 반환하므로 아무 것도 거기에없는 것입니다. 내 대답을 편집했습니다. –

답변

0

x % n은 0과 (n - 1) 사이의 정수로 평가됩니다.

x % 255 당신은 256와 255를 대체하거나, 대안 적으로, 비트 단위 AND를 수행하고 동일한 결과를위한 0xff으로한다 0, 254, 0이 아닌 255

의 정수로 평가되는 것을 의미한다. 후자는 더 빠르지 만, 컴파일러가 똑같은 바이트 코드를 최적화 할만큼 똑똑 할 수 있습니다.

+1

그건 그렇고, 이것은 C++'%'뿐만 아니라 일반적으로 정수 나누기 나머지 (모듈로)에서도 마찬가지입니다. 정밀도 :'x '가 -254에서 254 사이의 정수로 평가 될 수 있으므로 (OP의 코드는'((t % 255) + 255) 단순히 't % 255'가 아니라). –

+2

이전에 시도했지만 작동하지 않습니다. GF (2^8)에 대한 유한 한 이해로 exp/log 테이블의 패턴은 255 번째 요소에서 반복됩니다. 즉 요소 [1]은 [255]와 동일하므로 255 계수를 사용합니다. –

0

코드에 아무런 문제가 없습니다. 유한 필드 곱하기/나눗셈은 일반 산술과 다릅니다. cryptostackxchange에서 this question을 참조하십시오.

4

첫째,이 질문에 조심스럽게 모든 답변과 의견을 읽고 :

Addition and multiplication in a Galois Field

나는 코드가 OK라고 생각합니다,하지만 당신은 두 가지 문제가있다.

먼저 댓글이 잘못되었습니다. 0-254가 아닌 0-254 범위의 지수를 유지합니다.

둘째, "사소한"테스트 사례가 잘못되었습니다.

이 필드에서 숫자는 숫자의 이진 표현에서 얻은 계수의 다항식으로 생각하십시오. 예를 들어, 5 = 2^2 + 1이므로이 필드에서 "5"는 x^2 + 1을 의미합니다.

그래서 "5"* "3"= (x^2 + 1) * (x + 1) = x^3 + x^2 + x + 1 또는 "15". 이것이 테스트 케이스 assert((GF256elm(15)/GF256elm(5)) == GF256elm(3));이 작동하는 이유입니다. 5 배 3이 15라는 평범한 개념과는 아무런 관련이 없습니다. 다른 작업 테스트 케이스에서도 마찬가지입니다.이 테스트 케이스는 대부분 2의 제곱을 포함합니다.

그러나, "7"* "11"= (X^2 + X + 1) * (X^3 + X + 1) = X^5 + X^4 + 2 ×^3 + 2 ×^2 + 2x + 1

그러나 계수는 모두 모듈로 2이므로 실제로는 x^5 + x^4 + 1 = "49"입니다. 이것이 마지막 두 테스트 사례가 실패한 이유입니다.

시도하면 assert(GF256elm(49)/GF256elm(7) == GF256elm(11)); 체크 아웃해야합니다.

+0

내 의견에 설명 된대로 0에서 254 사이의 값을 넣었습니다 (의도적으로). 유한 필드에서 곱셈의 개념을 설명해 주셔서 감사합니다. 나는 실제로 유한 필드에 대한 이해가 부족하기 때문에 나쁜 테스트 케이스를 내려 놓았다. –

+0

@jtcwang하지만 _code_의 주석은 '//이 값을 0 ~ 255 사이로 줄입니다.' –

+0

이 수정됩니다. 목격 주셔서 감사합니다. –