ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

libsecp256k1比特币密码算法开源库(八)

2021-11-07 22:04:30  阅读:223  来源: 互联网

标签:FieldStorage 比特 self 元素 Field 开源 a.0 u32 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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有