【问题标题】:What implementions of Ed25519 exist?Ed25519 有哪些实现?
【发布时间】:2013-10-02 22:06:16
【问题描述】:

new SQRL authentication 方案依赖于 Daniel Bernstein 开发的 Curve Ed25519 加密。然而,为了开始实施这个方案,首先需要一个成熟的 Curve Ed25519 实施。

有人知道任何成熟的实现吗?对于 Java、.NET 或任何其他流行平台?

【问题讨论】:

  • Curve25519 和 Ed25519 的实现通常不同。它们使用相同的基础曲线,但表示形式不同。
  • 对于 c 实现,请使用 LibSodium,对于 .net,最好的版本可能是我自己的,但它还不是很成熟。
  • 对于 Curve25519 的稳定 .NET 实现,您可以在 GitHub 上尝试我自己的版本。我一直在生产中使用它,没有任何问题。
  • @quadfinity 这不是一个固定时间的实现。因此,它可能容易受到侧通道攻击,尤其是跨 VM 或跨进程变体的攻击。
  • @CodesInChaos 感谢您指出这一点。我已经实施了定时攻击对策。请随时查看更改。

标签: cryptography curve-25519 sqrl ed25519


【解决方案1】:

Curve25519 与 Ed25519

首先,Curve25519 和 Ed25519 并不完全相同。它们基于相同的基础曲线,但使用不同的表示。大多数实现都是针对 Curve25519 或 Ed25519,但可以在它们之间重用一些代码。

可以将 Ed25519 公钥转换为 Curve25519,但反过来会丢失一个符号位。即两个 Ed25519 公钥对应一个 Curve25519 公钥。私钥也非常相似。


关于实现,区分实际实现和将它们打包成可用形式的库很重要。

实际实现

djb 在SUPERCOP中的实现

  • Ref用c写的,很慢
  • djb 的 Ref10 用 c 编写,表现不错
  • djb的amd64-64-24k和amd64-51-30k,用汇编写的,大约是Ref10的两倍

他还在 NaCl 中写了一个较早的、不兼容的原型,不要使用那个

Floodyberry's donna 实施

包含多个变体,包括汇编和 c。有些针对 64 位进行了优化,有些针对 32 位进行了优化。

库

  • LibSodium

    C库,目前使用Ref10实现

    有bindings for many programming languages。它可能是最受欢迎的版本,也是我向大多数人推荐的版本。

    包含来自 NaCl 的许多其他加密功能,例如经过身份验证的加密 (XSalsa20Poly1305)、哈希、Curve25519 密钥交换。

  • Nightcracker's Ed25519

    C 库,使用Ref10 实现。

    这个库最有趣的特性是它支持使用 Ed25519 公钥进行密钥交换。但它不会散列共享密钥,因此不会产生与 Curve25519 相同的共享密钥。

    包含用于 Win32 和 Win64 的预构建二进制文件。

  • 我的C# port

    纯托管代码,可在 32 位和 64 位平台上保持不变。基于 Ref10。比 c 实现慢一点,但差异小得惊人。

    支持使用 Curve25519 和 Ed25519 密钥与 NaCl 兼容的密钥交换,并包含 NaCl 的许多其他加密功能。我的目标是与 LibSodium 类似的功能集。

    Ed25519 签名函数可以正常工作,并且已经进行了相当多的测试,但是库的其他部分有点粗糙。

  • 直接使用来自 SUPERCOP 或 Floodyberry 代码的实现。

    可能需要更多的工作来构建,但您将获得更高的性能 (~2x) 并且不需要携带不需要的代码。


我建议现在使用 LibSodium。它比较受欢迎并且维护得很好。性能不错,应该只会在真正签名繁重的应用程序中引起性能问题。

【讨论】:

  • 您说我的实现不会散列共享机密,并且不会产生与 Curve25519 相同的结果。但是,我不知道有任何散列的 Curve25519 实现,也没有为 Curve25519 输出 AFAIK 定义默认散列函数,所以我不确定是否应该添加散列。
  • 1) crypto_box_beforenm 使用一个特定的哈希值 2) Curve25519 论文描述了一种不同的哈希值。 3) 如果你只使用scalarmult 的输出作为 KDF 的输入,你可以跳过散列,这显然是散列。
  • 在这种情况下,我会保持它现在的样子 - 没有散列。这样您就可以与所有其他方案互操作,并在不需要时跳过散列。
  • @Codesinchaos 你的 C# 端口有 nuget 包吗?
  • @RLH 还没有。我只会在完成 API 后创建一个。
【解决方案2】:

添加到 CodesInChaos 的答案:

库

  • 我的Java port

    基于 Ref 10,并提供标准 JCA API,因此可以添加到加密提供者。

【讨论】:

  • 嗨,str4d 是否有将 REF10 移植到 JavaCard 的提示或技巧?
【解决方案3】:

到目前为止,最成熟和最有表现力的是丹尼尔伯恩斯坦自己写的。它可以在SUPERCOP 中找到。

但是,它的 API 相当笨拙,并且需要相当多的挖掘/提取才能得到你想要的。为了节省其他人的工作,我自己做了这个并将我的代码放在Github。

但请注意您的确切术语,Ed25519 和 Curve25519 是相关的,但不同的东西。你应该知道的是 Ed25519 是一个公钥/私钥签名系统,Curve25519 是一个密钥交换。 Ed25519 密钥对可以转换为 Curve25519 密钥对,反之我不太确定。我在 Github 上的库所做的是将所有内容保存在 Ed25519 密钥对中并转换为 Curve25519 以进行密钥交换。

【讨论】:

  • 如果我正确理解该网站,则密钥交换与 sqlr 无关,因此需要 Ed25519。它基于黄道 curve =)
【解决方案4】:

嵌入式实现

【讨论】:

    【解决方案5】:

    Go 1.17 (Q3 2021) 将附带一个new and faster implementation, done by Filo Sottile。

    见golang commit b0c49ae:

    此更改替换了crypto/ed25519/internal/edwards25519 package 使用来自filippo.io/edwards25519 的代码,显着更快、更安全, 经过良好测试(超过 1600 行新测试,99% 的测试覆盖率),以及 更好地记录(600 行新 cmets)实现。

    一些亮点:

    • 针对 64 位优化的不饱和 51 位肢体字段实现 架构和math/bits.Mul64 内在函数
    • 使用多宽度更有效的可变时间标量乘法 具有较大查找表的非相邻形式,用于固定基址
    • 一个安全的数学/big.Int 类 API,用于 Scalar、Point 和 field.Element 具有完全抽象的归约不变量的类型
    • 一个测试套件,包括一个探索边缘案例的测试/快速模糊器 不可能随机命中的值和系统测试 用于参数和接收器别名
    • 点解码规则严格匹配原逻辑 crypto/ed25519/internal/edwards25519,以避免共识问题
    • arm64 和 amd64 的符合 AssemblyPolicy 的程序集内核, 前者不到 20 行,后者由基于 github.com/mmcloughlin/avo 可以逐行查看 通用实现

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-09
      • 2016-01-20
      • 2013-08-22
      • 2011-03-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多