跳到主要内容

3. 将字节串编码到椭圆曲线 (Encoding Byte Strings to Elliptic Curves)

本节介绍了将字节串编码为椭圆曲线上的点的通用框架和接口。本节中的构造依赖于三个基本函数:

  • 函数 hash_to_field 将任意长度的字节串哈希为有限域 F 的一个或多个元素的列表;其实现在第 5 节中定义。
hash_to_field(msg, count)

输入 (Input):
- msg,包含要哈希的消息的字节串。
- count,要输出的 F 元素的数量。

输出 (Output):
- (u_0, ..., u_(count - 1)),域元素的列表。

步骤 (Steps): 在第 5 节中定义。
  • 函数 map_to_curve 从定义椭圆曲线 E 的有限域 F 的一个元素计算椭圆曲线 E 上的一个点。第 6 节描述了一系列曲线族的映射。
map_to_curve(u)

输入 (Input): u,域 F 的一个元素。
输出 (Output): Q,椭圆曲线 E 上的一个点。
步骤 (Steps): 在第 6 节中定义。
  • 函数 clear_cofactor 将曲线 E 上的任意点发送到 E 的子群 G。第 7 节描述了执行此操作的方法。
clear_cofactor(Q)

输入 (Input): Q,椭圆曲线 E 上的一个点。
输出 (Output): P,G 中的一个点。
步骤 (Steps): 在第 7 节中定义。

本节中定义的两种编码 (第 2.2.2 节) 具有相同的接口,并且都是随机预言机编码 (random-oracle encodings) (第 2.2.3 节)。两者都实现为上述三个基本函数的组合。两者之间的区别在于它们的输出从不同的分布中采样:

  • encode_to_curve 是从字节串到 G 中点的非均匀编码 (nonuniform encoding)。也就是说,其输出的分布在 G 中不是均匀随机的:encode_to_curve 可能输出的集合只是 G 中点的一小部分,并且此集合中的某些点比其他点更有可能被输出。第 10.4 节给出了 encode_to_curve 输出分布的更精确定义。
encode_to_curve(msg)

输入 (Input): msg,任意长度的字节串。
输出 (Output): P,G 中的一个点。

步骤 (Steps):
1. u = hash_to_field(msg, 1)
2. Q = map_to_curve(u[0])
3. P = clear_cofactor(Q)
4. return P
  • hash_to_curve 是从字节串到 G 中点的均匀编码 (uniform encoding)。也就是说,其输出的分布在统计上接近于 G 中的均匀分布。

当使用第 6 节中描述的任何 map_to_curve 函数实例化时,此函数适用于大多数需要返回 G 中点的随机预言机的应用。有关进一步讨论,请参见第 10.1 节。

hash_to_curve(msg)

输入 (Input): msg,任意长度的字节串。
输出 (Output): P,G 中的一个点。

步骤 (Steps):
1. u = hash_to_field(msg, 2)
2. Q0 = map_to_curve(u[0])
3. Q1 = map_to_curve(u[1])
4. R = Q0 + Q1 # 点加法 (Point addition)
5. P = clear_cofactor(R)
6. return P

第 8 节中的每个哈希到曲线套件 (hash-to-curve suite) 为特定椭圆曲线实例化这些编码函数之一。

3.1. 域分离要求 (Domain Separation Requirements)

本文档中定义的编码函数的所有使用必须 (MUST) 包含域分离 (domain separation) (第 2.2.5 节),以避免干扰类似功能的其他使用。

实例化 hash_to_curve 或 encode_to_curve 的多个独立实例的应用程序必须 (MUST) 在这些实例之间强制执行域分离。此要求适用于针对同一曲线的多个实例的情况以及针对不同曲线的多个实例的情况。(这是因为内部的 hash_to_field 原语 (第 5 节) 需要域分离来保证独立的输出。)

域分离通过域分离标签 (domain separation tag, DST) 来强制执行,DST 是根据以下要求构造的字节串:

  1. 标签必须 (MUST) 作为 DST 参数提供给 hash_to_field,如第 5 节所述。

  2. 标签必须 (MUST) 具有非零长度。推荐 (RECOMMENDED) 至少 16 字节的长度,以减少与其他应用程序发生碰撞的机会。

  3. 标签应该 (SHOULD) 以对应用程序唯一的固定标识字符串开头。

  4. 标签应该 (SHOULD) 包含版本号。

  5. 对于定义多个密码套件 (ciphersuites) 的应用程序,每个密码套件的标签必须 (MUST) 不同。为此,推荐 (RECOMMENDED) 在每个标签中包含密码套件标识符。

  6. 对于使用多个编码(无论是针对同一曲线还是不同曲线)的应用程序,每个编码必须 (MUST) 使用不同的标签。为此,推荐 (RECOMMENDED) 在域分离标签中包含编码的套件 ID (Suite ID) (第 8 节)。对于基于同一套件的独立编码,每个标签还应该 (SHOULD) 包含一个独特的标识符,例如 "ENC1" 和 "ENC2"。

作为示例,考虑一个名为 Quux 的虚构应用程序,它为不同曲线定义了几个不同的密码套件。合理的标签选择是 "QUUX-V-CS-",其中 是分别指示版本和密码套件的两位数字, 是密码套件 中使用的编码的套件 ID。

作为另一个示例,考虑一个名为 Baz 的虚构应用程序,它需要两个独立的随机预言机到同一曲线。这些预言机的合理标签选择分别是 "BAZ-V-CS--ENC1" 和 "BAZ-V-CS--ENC2",其中 如上所述。

上面给出的示例标签假定为 ASCII 编码的字节串,不带空终止符,这是推荐的格式 (RECOMMENDED format)。可以使用其他编码,但在所有情况下,作为字节序列的编码必须 (MUST) 明确指定。