2021SC@SDUSC 本篇博客是上一篇的延续,也是介绍一些libsecp256k1比特币密码算法中定义的数据结构和函数,我认为,在分析核心代码之前,应当了解一下算法用到的一些基础数据结构和算法,以便于后续的理解。 1、以压缩格式序列化ECDSA签名。 返回:1 Args:ctx:secp256k1上下文对象 Out:output64:指向存储压缩序列化的64字节数组的指针 In:sig:指向已初始化签名对象的指针
2、验证ECDSA签名。
返回: 1:正确的签名 0:签名不正确或不可解析 Args:ctx:secp256k1上下文对象,已初始化以进行验证。 In:sig:正在验证的签名。 msghash32:正在验证的32字节消息哈希。验证器必须确保应用加密。散列函数本身会将消息转换为散列函数,而不直接接受msghash32值。否则,就很容易做到在不知道密钥的情况下创建“有效”签名 pubkey:指向要验证的初始化公钥的指针。为避免接受可塑性签名,仅接受lower-S形式的ECDSA签名。
3、将签名转换为规范化的lower-S格式。
返回: 如果sigin未规范化,则返回1; 如果已规范化,则返回0。 Args:ctx:secp256k1上下文对象 Out:sigout:指向签名的指针,用于填充规范化表单,或者在输入已经规范化的情况下进行复制。(如果您只关心输入是否已规范化,则可以为NULL)。 In:sigin:指向要检查/规范化的签名的指针(可以与sigout相同)使用ECDSA,第三方可以伪造第二个不同的签名消息,提供单个初始签名,但不知道密钥。这是通过将S值与曲线的顺序求反来实现的,“翻转”不包含在签名中的随机点R的符号。伪造同一消息并不是普遍存在的问题,但在消息可塑性或签名唯一性很重要的系统中,这可能会导致问题。所有验证者都可以阻止这种伪造,迫使签名者使用规范化形式。当使用可变长度编码(如DER)时,lower-S形式平均略微减小签名的大小,并且验证成本较低,让它成为一个好的选择。始终使用lower-S的安全性得到了保证,因为任何人都可以在事后修改签名以强制执行此属性。
4、定义一种生成函数 RFC6979的一种实现(使用HMAC-SHA256)作为nonce生成函数。如果传递数据指针,则假定它是指向32字节额外熵的指针。
5、安全临时值生成函数 默认的安全临时值生成函数(当前等于secp256k1临时值函数\U rfc6979)
6、创建ECDSA签名。
返回: 1:已创建签名 0:nonce生成函数失败,或密钥无效。 Args:ctx:指向上下文对象的指针,已初始化用于签名。 Out:sig:指向将放置签名的数组的指针。 In:msghash32:正在签名的32字节消息哈希。 seckey:指向32字节密钥的指针。 noncefp:指向nonce生成函数的指针。如果为空,则使用secp256k1_nonce_function_default。 ndata:指向nonce生成函数使用的任意数据的指针(可以为空)。如果它是非NULL且如果使用secp256k1_nonce_function_default,则ndata必须是指向32字节附加数据的指针。创建的签名始终为小写形式。
7、验证ECDSA密钥。
当密钥被解释为整数时,如果该密钥不为0且小于secp256k1曲线顺序,则该密钥有效(最高有效字节优先)。随机均匀选择32字节字符串的概率,该字符串是无效的密钥可以忽略不计。 返回: 1:密钥有效 0:密钥无效 Args:ctx:指向上下文对象的指针。 In:seckey:指向32字节密钥的指针
8、计算密钥的公钥。
返回: 1:机密有效,公钥存储。 0:机密无效,请重试。 Args:ctx:指向上下文对象的指针,已初始化用于签名。 Out:pubkey:指向已创建公钥的指针。 In:seckey:指向32字节密钥的指针。
9、在适当的位置否定密钥。
返回: 如果给定的密钥无效,则为0 secp256k1_ec_seckey_验证,正确为1 Args:ctx:指向上下文对象的指针 In/Out:seckey:指向要求反的32字节密钥的指针。 密钥无效:secp256k1_ec_seckey_verify,此函数返回0和seckey将被设置为某个未指定的值。
10、在适当的位置否定公钥。
返回:1始终 Args:ctx:指向上下文对象的指针 In/Out:pubkey:指向要求反的公钥的指针
11、通过向密钥添加调整来调整密钥。
如果参数无效或生成的密钥无效(仅当调整是密钥的否定时),则返回0,否则返回1。 Args:ctx:指向上下文对象的指针。 输入/输出:seckey:指向32字节密钥的指针。如果根据secp256k1_ec_seckey_verify,密钥无效,则函数返回0,如果此函数返回0,则seckey将设置为某个未指定的值。 In:tweak32:指向32字节调整的指针。如果根据secp256k1_ec_seckey_verify,调整无效,则此函数返回0。对于均匀随机的32字节数组,无效的可能性可以忽略不计(大约1/2^128)。
12、通过向公钥添加调整次数生成器来调整公钥。
如果参数无效或生成的公钥无效,则返回0(仅当调整是对应密钥的否定时),否则返回1。 Args:ctx:指向为验证而初始化的上下文对象的指针。 In/Out:pubkey:指向公钥对象的指针。如果此函数返回0,则pubkey将设置为无效值。 In:tweak32:指向32字节调整的指针。如果根据secp256k1_ec_seckey_verify,调整无效,则此函数返回0。对于均匀随机的32字节数组,无效的可能性可以忽略不计(约为1/2^128)。
13、通过将密钥数乘调整来调整密钥。
如果参数无效,则返回0,否则返回1。 Args:ctx:指向上下文对象的指针。 输入/输出:seckey:指向32字节密钥的指针。如果根据secp256k1_ec_seckey_verify,密钥无效,则函数返回0。如果此函数返回0,则seckey将设置为某个未指定的值。 In:tweak32:指向32字节调整的指针。如果根据secp256k1_ec_seckey_verify,调整无效,则此函数返回0。对于均匀随机的32字节数组,无效的可能性可以忽略不计(约为1/2^128)。
14、通过将公钥数乘调整值来调整公钥。
如果参数无效,则返回0,否则返回1。 Args:ctx:指向为验证而初始化的上下文对象的指针。 In/Out:pubkey:指向公钥对象的指针。如果此函数返回0,则pubkey将设置为无效值。 In:tweak32:指向32字节调整的指针。如果根据secp256k1_ec_seckey_verify,调整无效,则此函数返回0。对于均匀随机的32字节数组,无效的可能性可以忽略不计(约为1/2^128)。
15、更新上下文随机化以防止侧通道泄漏。
返回: 1:随机化已成功更新或没有要随机化的内容 0:错误 Args:ctx:指向上下文对象的指针。 In:seed32:指向32字节随机种子的指针(NULL重置为初始状态),而secp256k1代码被写入为常量时间,无论秘密值是什么,未来的编译器可能会输出否,而且CPU可能不会发射相同的无线电频率或为所有值提取相同的功率。此函数提供一个种子,该种子被组合到盲值中:该盲值在每次乘法之前被添加(之后被删除),因此不会影响函数结果,但可以抵御依赖于任何输入依赖行为的攻击。此函数当前仅对初始化用于签名的上下文有效,因为随机化当前仅用于签名。但是,这并不能保证,将来可能会发生变化。在未初始化签名的上下文上调用此函数是安全的;然后它将无效并返回1。
16、将多个公钥添加到一起。 返回: 1:公钥的总和是有效的。 0:公钥的总和无效。 Args:ctx:指向上下文对象的指针。 Out:Out:指向用于放置结果公钥的公钥对象的指针。 In:ins:指向公钥指针数组的指针。 n:要加在一起的公钥数(必须至少为1)。
17、计算BIP-340中定义的标记哈希。
这对于创建消息散列和通过特定于应用程序的标记实现域分离非常有用。此函数返回SHA256(SHA256(标记)| | SHA256(标记)| | msg)。因此,针对特定标记优化的标记哈希实现可以在对标记哈希进行哈希处理后预计算SHA256状态。如果参数无效,则返回0,否则返回1。
Args:ctx:指向上下文对象的指针 Out:hash32:指向32字节数组的指针,用于存储结果哈希 In:tag:指向包含标记的数组的指针 taglen:标记数组的长度 msg:指向包含消息的数组的指针 msglen:消息数组的长度
|