libsecp256k1比特币密码算法开源库(八)
2021/11/7 22:09:41
本文主要是介绍libsecp256k1比特币密码算法开源库(八),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
2021SC@SDUSC
secp256k1曲线Curve结构定义
- FieldStorage域元素紧凑存储
- Field域元素
在libsecp256k1中对域元素进行了定义,其中Field定义secp256k1的有限域 G F ( p ) GF(p) GF(p)元素,但是在libsecp256k1库中定义的Field元素是320位,并不是常见的256位。在FieldStorage中实现紧凑的域元素存储,将Field中的元素压缩为256位,便于存储。
FieldStorage域元素紧凑存储
在libsecp256k1中对每个大数以数组的方式存储,每个数组元素为u32即32位比特,在FieldStorage中,每个Field元素为256位比特,用8个u32就可以表示。
impl FieldStorage { pub const fn new( d7: u32, d6: u32, d5: u32, d4: u32, d3: u32, d2: u32, d1: u32, d0: u32, ) -> Self { Self([d0, d1, d2, d3, d4, d5, d6, d7]) }
下面的代码实现了将320位的域元素压缩为256位存储的过程,压缩的过程没什么好说的,主要介绍一下rust语言的语法:
|表示位或,相同位只要有一个是1则返回1,否则返回0;
左移 <<操作数中的所有位向左移动指定位数,右边的位补0;
右移 >>操作数中的所有位向右移动指定位数,左边的位补0。
有了上面的语法想要看懂压缩过程就很容易了只需把对应数组元素0-1比特串做对应运算即可。可以看到赋值号=右侧有10个数组元素,到了赋值号左侧就只有8个,实现了将320位的域元素压缩为256位的存储过程。
impl Into<FieldStorage> for Field { fn into(self) -> FieldStorage { debug_assert!(self.normalized); let mut r = FieldStorage::default(); r.0[0] = self.n[0] | self.n[1] << 26; r.0[1] = self.n[1] >> 6 | self.n[2] << 20; r.0[2] = self.n[2] >> 12 | self.n[3] << 14; r.0[3] = self.n[3] >> 18 | self.n[4] << 8; r.0[4] = self.n[4] >> 24 | self.n[5] << 2 | self.n[6] << 28; r.0[5] = self.n[6] >> 4 | self.n[7] << 22; r.0[6] = self.n[7] >> 10 | self.n[8] << 16; r.0[7] = self.n[8] >> 16 | self.n[9] << 10; r } }
既然可以将Field元素压缩存储,那么必然需要将压缩的结果恢复出来,恢复的过程如下代码所示,还是一样的0-1比特串运算,其中&符号表示位与,即相同位都是1则返回1,否则返回0。
impl From<FieldStorage> for Field { fn from(a: FieldStorage) -> Field { let mut r = Field::default(); r.n[0] = a.0[0] & 0x3FFFFFF; r.n[1] = a.0[0] >> 26 | ((a.0[1] << 6) & 0x3FFFFFF); r.n[2] = a.0[1] >> 20 | ((a.0[2] << 12) & 0x3FFFFFF); r.n[3] = a.0[2] >> 14 | ((a.0[3] << 18) & 0x3FFFFFF); r.n[4] = a.0[3] >> 8 | ((a.0[4] << 24) & 0x3FFFFFF); r.n[5] = (a.0[4] >> 2) & 0x3FFFFFF; r.n[6] = a.0[4] >> 28 | ((a.0[5] << 4) & 0x3FFFFFF); r.n[7] = a.0[5] >> 22 | ((a.0[6] << 10) & 0x3FFFFFF); r.n[8] = a.0[6] >> 16 | ((a.0[7] << 16) & 0x3FFFFFF); r.n[9] = a.0[7] >> 10; r.magnitude = 1; r.normalized = true; r } }
Field域元素
每个Field元素320位,用10个u32数组元素表示。
impl Field { pub const fn new_raw( d9: u32, d8: u32, d7: u32, d6: u32, d5: u32, d4: u32, d3: u32, d2: u32, d1: u32, d0: u32, ) -> Self { Self { n: [d0, d1, d2, d3, d4, d5, d6, d7, d8, d9], magnitude: 1, normalized: false, } }
下面的内容涉将会及大端序小端序,大数的加法乘法运算以及field域元素的规格化处理,马上回来写
这篇关于libsecp256k1比特币密码算法开源库(八)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享