2021SC@SDUSC
结构体SecretKey表示私钥,私钥就是一个标量:
pub struct SecretKey(Scalar);
在libsecp256k1中的私钥共256比特,也就是32字节:
pub const SECRET_KEY_SIZE: usize = 32;
私钥SecretKey
下面是私钥相关的函数实现,主要包括私钥生成、私钥反序列化和私钥序列化。上一篇讲的公钥要通过私钥来生成,而这里的私钥要通过随机生成(这里的随机是指伪随机,因为纯软件(也就是仅靠代码)是无法实现真正的随机的)。私钥的序列化和反序列化与公钥就不一样了,因为公钥是Field,而私钥是Scalar,由于哈希摘要也是Scalar,并且同为256比特,这里调用的序列化和反序列化函数其实是一样的,但在细节上有些不同。
impl SecretKey {
pub fn parse(p: &[u8; util::SECRET_KEY_SIZE]) -> Result<SecretKey, Error> {
let mut elem = Scalar::default();
if !bool::from(elem.set_b32(p)) {
Self::try_from(elem)
} else {
Err(Error::InvalidSecretKey)
}
}
pub fn parse_slice(p: &[u8]) -> Result<SecretKey, Error> {
if p.len() != util::SECRET_KEY_SIZE {
return Err(Error::InvalidInputLength);
}
let mut a = [0; 32];
a.copy_from_slice(p);
Self::parse(&a)
}
pub fn random<R: Rng>(rng: &mut R) -> SecretKey {
loop {
let mut ret = [0u8; util::SECRET_KEY_SIZE];
rng.fill_bytes(&mut ret);
if let Ok(key) = Self::parse(&ret) {
return key;
}
}
}
pub fn serialize(&self) -> [u8; util::SECRET_KEY_SIZE] {
self.0.b32()
}
}
下面开始:
私钥生成
私钥生成首先是声明一个数组变量ret,它包含32个u8(即8比特)类型的数组元素,并且全部初始化为0,然后使用一个随机填充字节的函数fill_bytes将32个数组元素全部填充完。由于此时的32个u8类型的数组元素是序列化的,由于返回结果是一个Scalar类型的变量,因而需要经过parse函数反序列化后返回。
pub fn random<R: Rng>(rng: &mut R) -> SecretKey {
loop {
let mut ret = [0u8; util::SECRET_KEY_SIZE];
rng.fill_bytes(&mut ret);
if let Ok(key) = Self::parse(&ret) {
return key;
}
}
}
Scalar为256位标量值,使用8个32位的数组元素进行表示:
pub struct Scalar(pub [u32; 8]);
私钥反序列化
私钥反序列化需要调用一个set_b32函数,将序列化的数组变量p传入经函数set_b32反序列化,反序列化后要通过try_from函数检验私钥是否为0,检验不为0之后反序列化成功。
pub fn parse(p: &[u8; util::SECRET_KEY_SIZE]) -> Result<SecretKey, Error> {
let mut elem = Scalar::default();
if !bool::from(elem.set_b32(p)) {
Self::try_from(elem)
} else {
Err(Error::InvalidSecretKey)
}
}
下面是反序列化函数set_b32的实现过程,实现目标是把32个u8转化为8个u32:
#[must_use]
pub fn set_b32(&mut self, b32: &[u8; 32]) -> Choice {
self.0[0] = (b32[31] as u32)
| ((b32[30] as u32) << 8)
| ((b32[29] as u32) << 16)
| ((b32[28] as u32) << 24);
self.0[1] = (b32[27] as u32)
| ((b32[26] as u32) << 8)
| ((b32[25] as u32) << 16)
| ((b32[24] as u32) << 24);
self.0[2] = (b32[23] as u32)
| ((b32[22] as u32) << 8)
| ((b32[21] as u32) << 16)
| ((b32[20] as u32) << 24);
self.0[3] = (b32[19] as u32)
| ((b32[18] as u32) << 8)
| ((b32[17] as u32) << 16)
| ((b32[16] as u32) << 24);
self.0[4] = (b32[15] as u32)
| ((b32[14] as u32) << 8)
| ((b32[13] as u32) << 16)
| ((b32[12] as u32) << 24);
self.0[5] = (b32[11] as u32)
| ((b32[10] as u32) << 8)
| ((b32[9] as u32) << 16)
| ((b32[8] as u32) << 24);
self.0[6] = (b32[7] as u32)
| ((b32[6] as u32) << 8)
| ((b32[5] as u32) << 16)
| ((b32[4] as u32) << 24);
self.0[7] = (b32[3] as u32)
| ((b32[2] as u32) << 8)
| ((b32[1] as u32) << 16)
| ((b32[0] as u32) << 24);
let overflow = self.check_overflow();
self.reduce(overflow);
overflow
}
此外还有try_from函数检验私钥是否为0:
impl TryFrom<Scalar> for SecretKey {
type Error = Error;
fn try_from(scalar: Scalar) -> Result<Self, Error> {
if scalar.is_zero() {
Err(Error::InvalidSecretKey)
} else {
Ok(Self(scalar))
}
}
}
检验是否为0过程很简单,就是判断每个数组元素是否为0:
pub fn is_zero(&self) -> bool {
(self.0[0]
| self.0[1]
| self.0[2]
| self.0[3]
| self.0[4]
| self.0[5]
| self.0[6]
| self.0[7])
== 0
}
下面是一个复制函数,通过调用copy_from_slice将序列化的私钥复制进入序列化的数组p,在那之前判断数组长度length是否为32,不为32则返回错误:
pub fn parse_slice(p: &[u8]) -> Result<SecretKey, Error> {
if p.len() != util::SECRET_KEY_SIZE {
return Err(Error::InvalidInputLength);
}
let mut a = [0; 32];
a.copy_from_slice(p);
Self::parse(&a)
}
私钥序列化
私钥的序列化就是将8个u32转化为32个u8,这个过程调用b32函数实现:
pub fn serialize(&self) -> [u8; util::SECRET_KEY_SIZE] {
self.0.b32()
}
b32函数中创建了一个包含32个u8类型数组元素的数组变量bin,然后调用函数fill_b32将私钥序列化:
pub fn b32(&self) -> [u8; 32] {
let mut bin = [0u8; 32];
self.fill_b32(&mut bin);
bin
}
函数fill_b32实现过程如下所示:
pub fn fill_b32(&self, bin: &mut [u8; 32]) {
bin[0] = (self.0[7] >> 24) as u8;
bin[1] = (self.0[7] >> 16) as u8;
bin[2] = (self.0[7] >> 8) as u8;
bin[3] = (self.0[7]) as u8;
bin[4] = (self.0[6] >> 24) as u8;
bin[5] = (self.0[6] >> 16) as u8;
bin[6] = (self.0[6] >> 8) as u8;
bin[7] = (self.0[6]) as u8;
bin[8] = (self.0[5] >> 24) as u8;
bin[9] = (self.0[5] >> 16) as u8;
bin[10] = (self.0[5] >> 8) as u8;
bin[11] = (self.0[5]) as u8;
bin[12] = (self.0[4] >> 24) as u8;
bin[13] = (self.0[4] >> 16) as u8;
bin[14] = (self.0[4] >> 8) as u8;
bin[15] = (self.0[4]) as u8;
bin[16] = (self.0[3] >> 24) as u8;
bin[17] = (self.0[3] >> 16) as u8;
bin[18] = (self.0[3] >> 8) as u8;
bin[19] = (self.0[3]) as u8;
bin[20] = (self.0[2] >> 24) as u8;
bin[21] = (self.0[2] >> 16) as u8;
bin[22] = (self.0[2] >> 8) as u8;
bin[23] = (self.0[2]) as u8;
bin[24] = (self.0[1] >> 24) as u8;
bin[25] = (self.0[1] >> 16) as u8;
bin[26] = (self.0[1] >> 8) as u8;
bin[27] = (self.0[1]) as u8;
bin[28] = (self.0[0] >> 24) as u8;
bin[29] = (self.0[0] >> 16) as u8;
bin[30] = (self.0[0] >> 8) as u8;
bin[31] = (self.0[0]) as u8;
}
|