Go 표준 라이브러리 (또는 "x"패키지)에는 포인트 압축 해제 기능이 없으므로 직접 수행해야합니다 (또는 기존 구현을 찾으십시오).
구현이 너무 어렵지는 않지만 두 가지 사항을주의해야합니다.
기본적으로 X
값을 곡선 수식 Y2 = X3 + aX + b
에 연결하고 부호 비트를 사용하여 원하는 두 개의 뿌리를 결정해야합니다. 까다로운 점은이 모든 것이이 그룹의 전성기를 강 조할 필요가 있음을 기억하는 것입니다.
변경 가능한 값을 사용하기 때문에 Go’s big integer package이 약간 이상 할 수 있지만, 우리에게는 훨씬 편하게 들릴 modular square root function이 있습니다. 곡선 매개 변수는 crypto/elliptic
package에서 사용할 수 있지만 a
매개 변수는 항상이 곡선에 대해 -3
임을 알아야합니다.
당신이 compressed_bytes
에서의 following should work (주요 0x02
또는 0x03
포함) []byte
로 압축 지점이 가정. 이것은 방정식을 아주 직접적으로 구현 한 것으로, 주석과 많은 명명 된 변수로 분해되어 무슨 일이 일어나는지 설명하려고합니다. 약간 더 효율적인 (그리고 더 짧은) 구현을 위해 CurveParams.IsOnCurve
의 출처를 살펴보십시오. 모듈 식 제곱근까지는 기본적으로 같습니다.
compressed_bytes := //...
// Split the sign byte from the rest
sign_byte := uint(compressed_bytes[0])
x_bytes := compressed_bytes[1:]
// Convert to big Int.
x := new(big.Int).SetBytes(x_bytes)
// We use 3 a couple of times
three := big.NewInt(3)
// and we need the curve params for P256
c := elliptic.P256().Params()
// The equation is y^2 = x^3 - 3x + b
// First, x^3, mod P
x_cubed := new(big.Int).Exp(x, three, c.P)
// Next, 3x, mod P
three_X := new(big.Int).Mul(x, three)
three_X.Mod(three_X, c.P)
// x^3 - 3x ...
y_squared := new(big.Int).Sub(x_cubed, three_X)
// ... + b mod P
y_squared.Add(y_squared, c.B)
y_squared.Mod(y_squared, c.P)
// Now we need to find the square root mod P.
// This is where Go's big int library redeems itself.
y := new(big.Int).ModSqrt(y_squared, c.P)
if y == nil {
// If this happens then you're dealing with an invalid point.
// Panic, return an error, whatever you want here.
}
// Finally, check if you have the correct root by comparing
// the low bit with the low bit of the sign byte. If it’s not
// the same you want -y mod P instead of y.
if y.Bit(0) != sign_byte & 1 {
y.Neg(y)
y.Mod(y, c.P)
}
// Now your y coordinate is in y, for all your ScalarMult needs.
수학을 이해하는 누군가는 다른 ECC 라이브러리에서 구현을 해제해야한다고 생각합니다. 모범 사례를 요청하지만 실제로 구현을 요구하는 것 같습니다. –