Implementation
文件和實現之間的 EdDSA 點編碼差異
RFC 8032 描述了這樣的點編碼:
座標在 0 <= x,y < p 範圍內的曲線點 (x,y) 編碼如下。首先,將 y 座標編碼為 32 個八位字節的小端字元串。最後一個八位字節的最高有效位始終為零。要形成點的編碼,請將 x 座標的最低有效位複製到最後一個八位字節的最高有效位。
並像這樣實現它:
def point_compress(P): zinv = modp_inv(P[2]) x = P[0] * zinv % p y = P[1] * zinv % p return int.to_bytes(y | ((x & 1) << 255), 32, "little")
您能解釋一下“將 x 座標的最低有效位複製到最後一個八位字節的最高有效位”這句話中“複製”一詞的含義嗎?為什麼不複製程式碼中的位?為什麼它只是按位 OR ?
您能解釋一下“將 x 座標的最低有效位複製到最後一個八位字節的最高有效位”這句話中“複製”一詞的含義嗎?為什麼不複製程式碼中的位?為什麼它只是按位 OR ?
首先要注意;
點表示為擴展
座標的元組 (X, Y, Z, T),其中 x = X/Z, y = Y/Z, x*y = T/Z
所以
zinv
來自那裡x = P[0] * zinv % p y = P[1] * zinv % p
用於查找
x
和y
現在最後一行以一種簡單的方式完成了 RFC 描述的內容。
int.to_bytes(y | ((x & 1) << 255), 32, "little")
程式碼只是結果的展示。在你的程式環境中,你可以一點一點地使用複制,它會慢很多。
逐位或運算比逐位複制要快得多。此外,如您所見,沒有範圍檢查或
if
檢查邊界。由於公式是固定的,只要您的程式碼不洩漏資訊,您就可以使用所需的任何優化。最後一點:你用逐位複制來限制自己。結果不會將值複製到返回值中嗎?