跳到主要内容

JEP 339:爱德华曲线数字签名算法 (EdDSA)

概括

使用RFC 8032中描述的 Edwards 曲线数字签名算法 (EdDSA) 实现加密签名。

目标

EdDSA 是一种现代的椭圆曲线签名方案,与 JDK 中现有的签名方案相比,它具有多个优点。此 JEP 的主要目标是实现 RFC 8032 中标准化的此方案。此新签名方案不会取代 ECDSA。

其他实施目标:

  • 开发独立于平台的 EdDSA 实现,在相同的安全强度下,其性能比现有 ECDSA 实现(使用本机 C 代码)更好。例如,在约 126 位安全性下使用 Curve25519 的 EdDSA 应该与在约 128 位安全性下使用曲线 secp256r1 的 ECDSA 一样快。

  • 假设平台在恒定时间内执行 64 位整数加法/乘法,请确保计时与秘密无关。此外,实施不会因秘密而分支。这些属性对于防止旁路攻击非常有价值。

非目标

  • EdDSA 将仅在 SunEC 提供商中实施。在其他提供商中实施该标准并不是本 JEP 的目标。

  • EdDSA 的 API 和 SunEC 中的实现将不支持任意域参数。 EdDSA 的典型用途仅使用标准化参数集,例如 Ed25519 和 Ed448,这些参数集可以使用标识符指定,并且通常不需要对任意曲线参数的支持。 EdDSA API 应该允许通过扩展指定任意域参数。此类扩展超出了本 JEP 的范围。

  • EdDSA 与 JSSE for TLS 1.3 的集成将在该 JEP 完成后的后续增强中完成。

成功指标

  • RFC 8032 中的所有测试向量均通过。

  • 吞吐量(按照现有密钥协议基准中每秒派生的密钥来衡量)将优于所有平台上现有的 ECC 实现(具有类似的安全强度)。

  • 统计测试将表明签名操作的时间不会随私钥的变化而变化。

动机

与其他签名方案相比,EdDSA 因其更高的安全性和性能而受到欢迎,并且已经得到许多其他加密库(例如 OpenSSL 和 BoringSSL)的支持。此签名方案是 TLS 1.3 的可选组件,但也是 TLS 1.3 中允许的仅有的三种签名方案之一。某些用户可能拥有 EdDSA 证书,并且可能非常倾向于使用 EdDSA。这些用户将欣赏无需使用第三方库即可使用 EdDSA 的能力。开发 EdDSA 实现的另一个好处是,它使我们能够更轻松地开发和测试 TLS 1.3 中对该算法的支持。

描述

SunEC 提供商将添加新的SignatureKeyFactory、 和服务以支持 EdDSA。KeyPairGenerator新的类和接口将添加到API中来表示 EdDSA 密钥,并且将添加新的标准算法名称来描述 EdDSA 签名方案。 API 和实现将支持所有 EdDSA 变体(纯、预哈希和上下文)。

点算术将使用 RFC 8032 中定义的双精度和加法运算以及无分支条件分配运算来防止旁路攻击。现场算术将使用为 XDH ( JEP 324 ) 开发的模块化算术库。在对 JVM 和硬件行为进行一些合理假设的情况下,组合实现不会将秘密泄漏到计时和缓存侧通道中。

API 将重用NamedParameterSpec为 XDH 开发的类,以描述曲线域参数和 EdDSA 变体。将为 Edwards 曲线点、EdDSA 密钥和包括上下文信息的签名参数开发新的类和接口。

API 使用示例:

// example: generate a key pair and sign
KeyPairGenerator kpg = KeyPairGenerator.getInstance("Ed25519");
KeyPair kp = kpg.generateKeyPair();
// algorithm is pure Ed25519
Signature sig = Signature.getInstance("Ed25519");
sig.initSign(kp.getPrivate());
sig.update(msg);
byte[] s = sig.sign();

// example: use KeyFactory to contruct a public key
KeyFactory kf = KeyFactory.getInstance("EdDSA");
boolean xOdd = ...
BigInteger y = ...
NamedParameterSpec paramSpec = new NamedParameterSpec("Ed25519");
EdECPublicKeySpec pubSpec = new EdECPublicKeySpec(paramSpec, new EdPoint(xOdd, y));
PublicKey pubKey = kf.generatePublic(pubSpec);

备择方案

  • 本机实现(例如现有的 ECC 代码)可以提供更好的性能。 EdDSA 的性能应该与 XDH 类似,因此 Java 实现可能足够快。

  • 可以使用现有 ECC 代码中的点算术来实现此签名方案,但此方法无法提供 RFC 8032 的所有安全/性能优势。

  • 用户可以使用为 EdDSA 提供支持的第三方库。上面的动机部分描述了在 JDK 中包含 EdDSA 实现的动机。

  • 在技​​术上可能可以使用现有的 ECC API 类来指定 EdDSA 密钥和参数,但这会带来密钥滥用的重大风险。更多信息可以在 JDK-8166597 中找到。

测试

测试将包括 RFC 8032 中的测试向量,并通过针对小子组和非规范值等极端情况的测试进行增强。

风险和假设

EdDSA 实现将使用为 XDH 开发的字段算术库,因此存在相同的溢出风险和其他产生错误结果的错误。通过继续分析和测试现场算术库可以减轻这种风险。