libsecp256k1比特币密码算法开源库
Posted XHH_111
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了libsecp256k1比特币密码算法开源库相关的知识,希望对你有一定的参考价值。
2021SC@SDUSC
本篇博客介绍了一些libsecp256k1算法中的定义的函数和数据结构,编程语言为C语言。参考一些论文以及源代码注释。
注:除非明确说明,否则所有指针参数都不能为NULL。
API参数的顺序:上下文指针->输出参数->输入参数。(不是数据指针的参数排在最后,从复杂到不复杂:函数指针、算法名称、消息、无效指针、计数、标志、布尔值。不透明数据指针跟随它们要传递到的函数指针)
1.保存上下文信息的不透明数据结构(预计算表等)
上下文结构的目的是缓存大型预计算数据表。构建和维护随机数据的成本都很高,不要为每个操作创建新的上下文对象,因为构造要比所有其他API调用慢得多(大约比ECDSA验证慢100倍)。构造的上下文可以从多个线程安全地使用,但API调用使用指向上下文的非常量指针需要独占访问它。
2、包含可重写“暂存空间”的不透明数据结构
此结构的目的是替换动态内存分配,因为我们的目标架构可能不可用。它本质上是一个可调整大小(在指定参数内)的字节块,最初通过内存分配或TODO作为指向某个固定可重写空间的指针创建。与上下文对象不同,如果没有额外的同步逻辑,就无法在线程之间安全地共享该对象。
3、包含已解析的有效公钥的不透明的数据结构
内部数据的精确表示由实现定义,不能保证在不同平台或版本之间可移植。但是,它的大小保证为64字节,并且可以安全地复制/移动。允许转换为适合存储或传输的格式,或者进行比较密钥。
4、包含已解析ECDSA签名的不透明结构化数据。
内部数据的精确表示由实现定义,而不是保证在不同平台或版本之间可移植。它保证大小为64字节,并且可以安全地复制/移动。允许转换为适合存储、传输或存储的格式。
5、指向函数的指针,用于确定地生成nonce
如果成功生成nonce,则返回1;失败返回0。
Out:
nonce32:指向要由函数填充的32字节数组的指针。
In:
msg32:正在验证的32字节消息哈希(将不为空)
key32:指向32字节密钥的指针(不会为空)
algo16:指向描述签名的16字节数组的指针算法(为了兼容性,ECDSA将为空)。
数据:通过的任意数据指针。
尝试:我们试图找到一个nonce的迭代次数。这几乎总是0,但尝试值不同,需要生成不同的nonce。除了测试用例之外,这个函数应该计算信息、算法、密钥和尝试。
6、secp256k1_NO_BUILD当在构建时使用此标头时,需要设置SECP256K1_构建定义以正确设置导出属性和空值检查。这通常由secp256k1.c完成,但为了防止在secp256k1.c有机会设置定义之前包含此标头(例如,通过仅包含secp256k1.c的测试线束),我们在处理此标头时设置secp256k1_NO_BUILD,而不使用BUILD define,以便捕获此情况。
7、
本段代码是设置SECP256K1_BUILD来避免编译器进行一些无意义的空检查。
8、定义了一些标志
所有标志的低8位表示它们的用途。不要直接使用。
高位包含实际数据。不要直接使用。
要传递到secp256k1_上下文_创建、secp256k1_上下文_预分配_大小和secp256k1_上下文_预分配_创建。
要传递给secp256k1_ec_pubkey_serialize的标志
用于标记各种编码曲线点的前缀字节,用于特定目的
9、创建一个secp256k1上下文对象(在动态分配的内存中)。
此函数使用malloc分配内存。保证此函数的每次调用最多调用一次malloc。
返回:新创建的上下文对象。
In:flags:初始化上下文的哪些部分。
10、复制secp256k1上下文对象(到动态分配的内存中)
此函数使用malloc分配内存。保证此函数的每次调用最多调用一次malloc。
返回:新创建的上下文对象。
Args:ctx:要复制的现有上下文
11.销毁secp256k1上下文对象(在动态分配的内存中创建)以后不能使用上下文指针,要销毁的上下文必须使用secp256k1_context_create或secp256k1_context_clone创建。如果上下文是使用secp256k1_context_preallocated_create或secp256k1_context_preallocated_clone行为没有定义。在这种情况下,必须使用secp256k1_context_preallocated_destroy。
Args:ctx:要销毁的现有上下文,使用secp256k1_上下文_创建或secp256k1_上下文_克隆
12、设置在将非法参数传递给API调用时要调用的回调函数。
它只会触发标题中明确提到的冲突。其原理是不应该通过特定的返回值来处理这些问题,因为调用代码不应该有分支来处理代码本身被破坏的情况
此类错误和默认值(崩溃)可能是不可取的。当触发此回调时,调用的API函数保证不会导致崩溃,尽管其返回值和输出参数未定义。当未调用此函数(或使用fn==NULL调用)时,然后将使用默认处理程序。库提供一个默认处理程序,将消息写入stderr并调用abort。如果定义了预处理器宏USE\\u EXTERNAL\\u default\\u回调,则可以在链接时替换此默认处理程序,如果生成已配置–enable EXTERNAL default回调,则会出现这种情况。然后必须提供以下两个符号来链接:void secp256k1_default_非法_callback_fn(const charmessage,voiddata);void secp256k1_默认_错误_回调_fn(常量字符消息,void数据);库甚至可以在使用secp256k1_context_set_非法_回调或secp256k1_context_set_error_回调设置正确的回调数据指针之前调用这些默认处理程序,例如,当创建上下文失败时。在这种情况下,将调用相应的默认处理程序,并将数据指针参数设置为NULL。
Args:ctx:现有上下文对象。
In:fun:一个指针,指向一个函数,当一个非法参数被激活时调用该函数传递给API,获取消息和不透明指针。(NULL还原默认处理程序。)
数据:传递给上面fun的不透明指针对于默认处理程序必须为NULL。
13、设置内部一致性检查失败时调用的回调函数。
默认值是崩溃。这只能在硬件故障、错误编译、内存损坏、库中存在严重错误或其他可能导致未定义行为的错误时触发。它不会因为API的不正确使用而触发。在这个回调返回后,任何事情都可能发生,包括崩溃。
Args:ctx:现有上下文对象。
In:fun:当发生内部错误时,指向要调用的函数的指针,
获取消息和不透明指针(NULL)将恢复。
数据:传递给上面fun的不透明指针对于默认处理程序必须为NULL。
14、创建一个secp256k1暂存空间对象。
返回:新创建的暂存空间。
Args:ctx:现有上下文对象。
In:size:可用作暂存空间的内存量。将分配一些额外(<100字节)用于额外记帐。
15、销毁secp256k1划痕空间。
之后不得使用指针
Args:ctx:secp256k1上下文对象。
划痕:销毁的空间
16、将可变长度公钥解析到pubkey对象中。
如果公钥完全有效,则返回:1。
如果无法分析公钥或公钥无效,则返回0。
Args:ctx:secp256k1上下文对象。
Out:pubkey:指向pubkey对象的指针。如果返回1,则将其设置为输入的解析版本。如果不是,则其值未定义。
In:input:指向序列化公钥的指针
inputlen:输入指向的数组的长度
此函数支持解析压缩(33字节,头字节0x02或0x03)、未压缩(65字节,头字节0x04)或混合(65字节,头字节0x06或0x07)格式的公钥。
17、将pubkey对象序列化为序列化的字节序列。
返回:1
Args:ctx:secp256k1上下文对象。
Out:output:指向65字节(如果压缩==0)或33字节(如果压缩 ==1)字节数组的指针,用于将序列化键放入其中。
In/Out:outputlen:指向整数的指针,该整数最初设置为输出的大小,并被写入的大小覆盖。
In:pubkey:指向包含初始化公钥的secp256k1_pubkey的指针。
标志:如果序列化应为压缩格式,则SECP256K1_EC_压缩,否则SECP256K1_EC_未压缩。
18、比较两个公钥顺序
使用词典比较两个公钥顺序:如果第一个公钥小于第二个公钥,返回<0;如果第一个公钥大于第二个公钥,返回>0;如果两个公钥相等,返回0。
Args:ctx:secp256k1上下文对象。
In:pubkey1:要比较的第一个公钥
pubkey2:要比较的第二个公钥
19、以压缩(64字节)格式解析ECDSA签名。
返回:当签名可以被解析时返回1,否则返回0。
Args:ctx:secp256k1上下文对象
Out:sig:指向签名对象的指针
In:input64:指向要分析的64字节数组的指针
签名必须包含一个32字节的大端值R,后跟一个32字节的大端值S。如果R或S不在[0…order-1]范围内,则编码无效。编码中允许值为0的R和S。调用后,sig将始终初始化。如果解析失败或R或S为零,则生成的sig值将保证在任何情况下都无法通过验证消息和公钥。
20、解析DER ECDSA签名。
返回:当签名可以被解析时返回1,否则返回0。
Args:ctx:secp256k1上下文对象
Out:sig:指向签名对象的指针
In:input:指向要解析的签名的指针inputlen:指向要输入的数组的长度。此函数将接受任何有效的DER编码签名,即使编码的数字超出范围。调用后,sig将始终初始化。如果解析失败或编码的数字超出范围,则保证对每条消息和公钥的签名验证都会失败。
以上是关于libsecp256k1比特币密码算法开源库的主要内容,如果未能解决你的问题,请参考以下文章