libsecp256k1比特币密码算法开源库(八)
作者:互联网
2021SC@SDUSC
secp256k1曲线Curve结构定义
在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域元素的规格化处理,马上回来写
标签:FieldStorage,比特,self,元素,Field,开源,a.0,u32,libsecp256k1 来源: https://blog.csdn.net/qq_50680426/article/details/121004758