JEP 339: Edwards-Curve Digital Signature Algorithm (EdDSA) | Edwards 曲线数字签名算法(EdDSA)
摘要
使用 RFC 8032 中描述的 Edwards-Curve Digital Signature Algorithm(EdDSA)实现加密签名。
目标
EdDSA 是一种现代的椭圆曲线签名方案,相较于 JDK 中现有的签名方案具有多个优势。本 JEP 的主要目标是实现 RFC 8032 中标准化的该方案。这种新的签名方案不会取代 ECDSA。
额外的实现目标:
开发一种与平台无关的 EdDSA 实现,在相同的安全强度下,其性能应优于现有的 ECDSA 实现(后者使用本地 C 代码)。例如,使用 Curve25519 在约 126 位安全性的 EdDSA 应与使用 secp256r1 曲线在约 128 位安全性的 ECDSA 一样快。
确保计时与密钥无关,假设平台在常数时间内执行 64 位整数加法和乘法。此外,实现不会在密钥上进行分支。这些属性对于防止侧信道攻击非常有价值。
非目标
EdDSA 仅在 SunEC 提供程序中实现。本 JEP 的目标不是在其他提供程序中实现此标准。
EdDSA 的 API 和 SunEC 中的实现将不支持任意的域参数。EdDSA 的典型用法仅使用标准化的参数集,如 Ed25519 和 Ed448,这些可以通过标识符指定,并且通常不需要支持任意的曲线参数。EdDSA API 应通过扩展来允许指定任意的域参数。此类扩展不在本 JEP 的范围内。
在本 JEP 完成后,将在后续增强中完成 EdDSA 与 JSSE 的 TLS 1.3 集成。
成功指标
RFC 8032 中的所有测试向量均通过。
吞吐量(通过现有密钥协商基准中的每秒派生密钥数来衡量)将在所有平台上与现有 ECC 实现(具有类似安全强度)相比较为有利。
统计测试将显示签名操作的计时不会随私钥的变化而变化。
动机
EdDSA 因其在安全性和性能方面的改进而备受青睐,并且已经在许多其他加密库(如 OpenSSL 和 BoringSSL)中得到支持。此签名方案是 TLS 1.3 的可选组件,但它是 TLS 1.3 中仅允许的三种签名方案之一。一些用户可能拥有 EdDSA 证书,并可能强烈倾向于使用 EdDSA。这些用户将欣赏能够使用 EdDSA 而不必使用第三方库的能力。开发 EdDSA 实现的另一个好处是,它使我们能够更轻松地开发和测试 TLS 1.3 中对该算法的支持。
描述
SunEC 提供程序将添加新的 Signature
、KeyFactory
和 KeyPairGenerator
服务来支持 EdDSA。将向 API 添加新的类和接口来表示 EdDSA 密钥,并将添加新的标准算法名称来描述 EdDSA 签名方案。该 API 和 实现 将支持所有 EdDSA 变体(纯、预哈希和上下文)。
点算术将使用 RFC 8032 中定义的加法和双运算以及无分支的条件赋值运算来防止侧信道攻击。字段算术将使用为 XDH 开发的模算术库(JEP 324)。在 JVM 和硬件行为的某些合理假设下,结合实现将不会将秘密泄露到计时和缓存侧信道中。
API 将重用为 XDH 开发的 NamedParameterSpec
类来描述曲线域参数和 EdDSA 变体。将为 Edwards 曲线点、EdDSA 密钥和签名参数(包括上下文信息)开发新的类和接口。
API 使用示例:
// 示例:生成密钥对并签名
KeyPairGenerator kpg = KeyPairGenerator.getInstance("Ed25519");
KeyPair kp = kpg.generateKeyPair();
// 算法是纯 Ed25519
Signature sig = Signature.getInstance("Ed25519");
sig.initSign(kp.getPrivate());
sig.update(msg);
byte[] s = sig.sign();
// 示例:使用 KeyFactory 构造公钥
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 支持的第三方库。在上面的“动机”部分中描述了将 EdDSA 实现包含在 JDK 中的原因。
从技术上讲,可以使用现有的 ECC API 类来指定 EdDSA 密钥和参数,但这会存在严重的密钥误用风险。有关更多信息,请参阅 JDK-8166597。
测试
测试将包括 RFC 8032 中的测试向量,并增加了对特殊情况(如小子群和非规范值)的测试。
风险和假设
EdDSA 实现将使用为 XDH 开发的字段算术库,因此存在溢出和其他错误产生不正确结果的风险。通过继续分析和测试字段算术库来降低这种风险。
摘要
Implement cryptographic signatures using the Edwards-Curve Digital Signature Algorithm (EdDSA) as described by RFC 8032.
目标
EdDSA is a modern elliptic curve signature scheme that has several advantages over the existing signature schemes in the JDK. The primary goal of this JEP is an implementation of this scheme as standardized in RFC 8032. This new signature scheme does not replace ECDSA.
Additional implementation goals:
Develop a platform-independent implementation of EdDSA with better performance than the existing ECDSA implementation (which uses native C code) at the same security strength. For example, EdDSA using Curve25519 at ~126 bits of security should be as fast as ECDSA using curve secp256r1 at ~128 bits of security.
Ensure that the timing is independent of secrets, assuming the platform performs 64-bit integer addition/multiplication in constant time. In addition, the implementation will not branch on secrets. These properties are valuable for preventing side-channel attacks.
非目标
EdDSA will only be implemented in the SunEC provider. It is not a goal of this JEP to implement this standard in other providers.
The API for EdDSA and the implementation in SunEC will not support arbitrary domain parameters. Typical uses of EdDSA only use standardized parameter sets such as Ed25519 and Ed448 which can be specified using identifiers, and support for arbitrary curve parameters is not typically needed. The EdDSA API should permit, through extension, the specification of arbitrary domain parameters. Such extension is outside of the scope of this JEP.
Integration of EdDSA with JSSE for TLS 1.3 will be completed in a follow-on enhancement after this JEP is complete.
成功指标
All test vectors in RFC 8032 pass.
Throughput (as measured by derived keys per second in the existing key agreement benchmark) will compare favorably to the existing ECC implementation (of similar security strength) on all platforms.
A statistical test will show that the timing of the signing operation does not vary with the private key.
动机
EdDSA is in demand due to its improved security and performance compared to other signature schemes, and is already supported in many other crypto libraries such as OpenSSL and BoringSSL. This signature scheme is an optional component of TLS 1.3, but is one of only three signature schemes that are allowed in TLS 1.3. Some users may have EdDSA certificates, and may have a strong preference to use EdDSA. These users will appreciate the ability to use EdDSA without having to use a third-party library. An additional benefit of developing an implementation of EdDSA is that it allows us to more easily develop and test the support of this algorithm in TLS 1.3.
描述
New Signature
, KeyFactory
, and KeyPairGenerator
services will be added to the SunEC provider to support EdDSA. New classes and interfaces will be added to the API to represent EdDSA keys, and new standard algorithm names will be added to describe EdDSA signature schemes. The API and implementation will support all EdDSA variants (pure, prehashed, and context).
The point arithmetic will use the double and add operations defined in RFC 8032 along with a branch-free conditional assignment operation to prevent side-channel attacks. The field arithmetic will use the modular arithmetic library that was developed for XDH (JEP 324). The combined implementation will not leak secrets into timing and cache side channels, under some reasonable assumptions on the behavior of the JVM and hardware.
The API will reuse the NamedParameterSpec
class developed for XDH in order to describe curve domain parameters and EdDSA variants. New classes and interfaces will be developed for Edwards curve points, EdDSA keys, and signature parameters which include context information.
Example API usage:
// 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);
替代方案
A native implementation (such as the existing ECC code) may provide better performance. The performance of EdDSA should be similar to that of XDH, so a Java implementation will likely be fast enough.
It is possible to implement this signature scheme using the point arithmetic in the existing ECC code, but this approach does not provide all of the security/performance benefits of RFC 8032.
Users could use a third-party library that provides support for EdDSA. The motivation for including an implementation of EdDSA in the JDK is described in the Motivation section, above.
It may be technically possible to use the existing ECC API classes to specify EdDSA keys and parameters, but this would present a significant risk of key misuse. More information can be found in JDK-8166597.
测试
Testing will include the test vectors from RFC 8032, augmented with tests for corner cases such as small subgroups and non-canonical values.
风险和假设
The EdDSA implementation will use the field arithmetic library developed for XDH, so there is the same risk of overflow and other bugs that produce incorrect results. This risk is mitigated by continuing to analyze and test the field arithmetic library.