使用 xedDSA 驗證功能驗證 EdDSA 簽名。
我遇到了一個問題,我使用 pynacl (https://pynacl.readthedocs.io/en/stable/signing/) ed25519 實現之類的庫生成簽名,然後當我使用 xedDSA 的驗證功能(https:// /github.com/signalapp/curve25519-java/blob/master/android/jni/ed25519/additions/xeddsa.c#L45)它有時會通過,有時會失敗。
這似乎與生成簽名的 priv/pub 密鑰對有關。一旦密鑰對生成 xedDSA 函式可以驗證的簽名,所有後續簽名也會從同一密鑰對正確驗證。我將 pynacl 提供的 ed25519 公鑰轉換為 curve25519 公鑰 (
verify_key.to_curve25519_public_key()
),然後將其傳遞給 xedDSA 函式。在這裡的介紹中:https ://signal.org/docs/specifications/xeddsa/#curve25519
據說 ed25519 簽名將由 xedDSA 驗證功能正確驗證。但這裡不是這種情況。
誰能告訴我為什麼會這樣?我非常有信心它與密鑰生成以及隨後將 ed pubkey 轉換為曲線 pubkey 有關。但我對加密的了解還不夠,無法確定問題所在。
從您的連結:
XEd25519 簽名是有效的 Ed25519 簽名,反之亦然,前提是使用雙有理映射轉換公鑰。
不幸的是,反之亦然是錯誤的。
XEd25519 的工作原理是要求私鑰是正數,因為它將產生正向的愛德華茲公鑰。這是通過否定私鑰來獲得的,如果它產生一個帶有負數的公鑰 $ x $ . (在 ed25519 中 LSB 意義上的負和正)
假設這在驗證中有效,但如果簽名是使用 ed25519 生成的,則不會。
更具體地說,在 ed25519 中,您可以同時擁有正公鑰和負公鑰 $ A $ . 然後您的簽名計算為: $ R = rB, s = r + ha $ 請注意,在 ed25519 你有 $ A = aB $ . 驗證是通過驗證 $ R = sB - hA $ .
在 ed25519 這有效,因為 $ R = rB = (r + ha)B - h(aB) $ .
但是,當使用 XEd25519 時,情況會發生變化,因為公鑰被隱式假定為正數(curve25519 缺少符號資訊,因此應該做出一些假設),因此您最終會在驗證方程中出現符號位翻轉: $ rB \neq (r + ha)B - h*(-A) $ .
因此,您可以通過這種方式僅驗證由帶有正公鑰的 ed25519 密鑰對生成的簽名。
修復:我認為您在測試中可能沒問題 $ R = (r + ha)B \pm hA $ 如果簽名有效,這將在兩種情況之一中成立,但我想當您的實現使用雙基標量乘法時,這將是一個問題,這對於簽名驗證來說非常常見。一個更好的主意是用 qDSA 替換 XEd25519,這是在蒙哥馬利曲線上進行簽名的更自然的方式