如何理解签名体制包含3个算法:KeyGen(密钥生成算法),Sign(签名算法),Verify(验证算法);
以及以下话:
“公钥加密,私钥解密是密送,保证消息即使公开也只有私钥持有者能读懂。
私钥加密,公钥解密是签名,保证消息来源是私钥持有者。”
什么是公钥,什么是私钥?长什么形状?
一、标准库的hash值
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
fn calculate_hash<T: Hash>(t: &T) -> u64 {
let mut s = DefaultHasher::new();
t.hash(&mut s);
s.finish()
}
fn main() {
let st = SystemTime::now();
let text = "10086".as_bytes();
println!("text:{:?}", text);
let mut hasher1 = DefaultHasher::new();
hasher1.write(text);
println!("Hash1(低16位表示) is {:x}", hasher1.finish());
println!("Hash1 is {}", hasher1.finish());
let mut hasher2 = DefaultHasher::new();
text.hash(&mut hasher2);
println!("Hash2(低16位表示) is {:x}", hasher2.finish());
println!("Hash2 is {}", hasher2.finish());
println!("calculate_hash:->Hash :{:?}", calculate_hash(&text));
let mt1 = SystemTime::now();
println!("is_fit_num time:{:?}", mt1.duration_since(st).unwrap());
thread::sleep_ms(500000);
}
output:
text:[49, 48, 48, 56, 54]
Hash1(低16位表示) is 85f84a89780553ce
Hash1 is 9653547755553248206
Hash2(低16位表示) is 4b5a264ac7932dc5
Hash2 is 5429694403366301125
calculate_hash:->Hash :5429694403366301125
思考 : hash1为什么和hash2不同?
二、关于keypair、signature、verify 三部曲
我们看rust-crypto库的原代码的例子
https://github.com/DaGenix/rust-crypto/blob/cc1a5fde1ce957bd1a8a2e30169443cdb4780111/src/ed25519.rs
use digest::Digest;
use sha2::{Sha512};
use curve25519::{GeP2, GeP3, ge_scalarmult_base, sc_reduce, sc_muladd, curve25519, Fe};
use util::{fixed_time_eq};
use std::ops::{Add, Sub, Mul};
static L: [u8; 32] =
[ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x14, 0xde, 0xf9, 0xde, 0xa2, 0xf7, 0x9c, 0xd6,
0x58, 0x12, 0x63, 0x1a, 0x5c, 0xf5, 0xd3, 0xed ];
pub fn keypair(seed: &[u8]) -> ([u8; 64], [u8; 32]) {
let mut secret: [u8; 64] = {
let mut hash_output: [u8; 64] = [0; 64];
let mut hasher = Sha512::new();
hasher.input(seed);
hasher.result(&mut hash_output);
hash_output[0] &= 248;
hash_output[31] &= 63;
hash_output[31] |= 64;
hash_output
};
let a = ge_scalarmult_base(&secret[0..32]);
let public_key = a.to_bytes();
for (dest, src) in (&mut secret[32..64]).iter_mut().zip(public_key.iter()) {
*dest = *src;
}
for (dest, src) in (&mut secret[0..32]).iter_mut().zip(seed.iter()) {
*dest = *src;
}
(secret, public_key)
}
pub fn signature(message: &[u8], secret_key: &[u8]) -> [u8; 64] {
let seed = &secret_key[0..32];
let public_key = &secret_key[32..64];
let az: [u8; 64] = {
let mut hash_output: [u8; 64] = [0; 64];
let mut hasher = Sha512::new();
hasher.input(seed);
hasher.result(&mut hash_output);
hash_output[0] &= 248;
hash_output[31] &= 63;
hash_output[31] |= 64;
hash_output
};
let nonce = {
let mut hash_output: [u8; 64] = [0; 64];
let mut hasher = Sha512::new();
hasher.input(&az[32..64]);
hasher.input(message);
hasher.result(&mut hash_output);
sc_reduce(&mut hash_output[0..64]);
hash_output
};
let mut signature: [u8; 64] = [0; 64];
let r: GeP3 = ge_scalarmult_base(&nonce[0..32]);
for (result_byte, source_byte) in (&mut signature[0..32]).iter_mut().zip(r.to_bytes().iter()) {
*result_byte = *source_byte;
}
for (result_byte, source_byte) in (&mut signature[32..64]).iter_mut().zip(public_key.iter()) {
*result_byte = *source_byte;
}
{
let mut hasher = Sha512::new();
hasher.input(signature.as_ref());
hasher.input(message);
let mut hram: [u8; 64] = [0; 64];
hasher.result(&mut hram);
sc_reduce(&mut hram);
sc_muladd(&mut signature[32..64], &hram[0..32], &az[0..32], &nonce[0..32]);
}
signature
}
fn check_s_lt_l(s: &[u8]) -> bool
{
let mut c: u8 = 0;
let mut n: u8 = 1;
let mut i = 31;
loop {
c |= ((((s[i] as i32) - (L[i] as i32)) >> 8) as u8) & n;
n &= (((((s[i] ^ L[i]) as i32)) - 1) >> 8) as u8;
if i == 0 {
break;
} else {
i -= 1;
}
}
c == 0
}
pub fn verify(message: &[u8], public_key: &[u8], signature: &[u8]) -> bool {
if check_s_lt_l(&signature[32..64]) {
return false;
}
let a = match GeP3::from_bytes_negate_vartime(public_key) {
Some(g) => g,
None => { return false; }
};
let mut d = 0;
for pk_byte in public_key.iter() {
d |= *pk_byte;
}
if d == 0 {
return false;
}
let mut hasher = Sha512::new();
hasher.input(&signature[0..32]);
hasher.input(public_key);
hasher.input(message);
let mut hash: [u8; 64] = [0; 64];
hasher.result(&mut hash);
sc_reduce(&mut hash);
let r = GeP2::double_scalarmult_vartime(hash.as_ref(), a, &signature[32..64]);
let rcheck = r.to_bytes();
fixed_time_eq(rcheck.as_ref(), &signature[0..32])
}
pub fn exchange(public_key: &[u8], private_key: &[u8]) -> [u8; 32] {
let ed_y = Fe::from_bytes(&public_key);
// Produce public key in Montgomery form.
let mont_x = edwards_to_montgomery_x(ed_y);
// Produce private key from seed component (bytes 0 to 32)
// of the Ed25519 extended private key (64 bytes).
let mut hasher = Sha512::new();
hasher.input(&private_key[0..32]);
let mut hash: [u8; 64] = [0; 64];
hasher.result(&mut hash);
// Clamp the hash such that it is a valid private key
hash[0] &= 248;
hash[31] &= 127;
hash[31] |= 64;
let shared_mont_x : [u8; 32] = curve25519(&hash, &mont_x.to_bytes()); // priv., pub.
shared_mont_x
}
三、如何用?
看一个私钥签名,公钥解密的例子。
extern crate crypto;
use crypto::*;
use ed25519::{keypair, signature, verify, exchange};
use curve25519::{curve25519_base, curve25519};
use digest::Digest;
use sha2::Sha512;
fn main() {
let seed: &[u8] = &[0x26, 0x27, 0xf6, 0x85, 0x97, 0x15, 0xad, 0x1d, 0xd2, 0x94, 0xdd, 0xc4, 0x76, 0x19, 0x39, 0x31, 0xf1, 0xad, 0xb5, 0x58, 0xf0, 0x93, 0x97, 0x32, 0x19, 0x2b, 0xd1, 0xc0, 0xfd, 0x16, 0x8e, 0x4e];//32位
// KEYGEN
let (private_key, public_key) = keypair(seed); //[U8,64]
let message = b"This is my message!";
//私钥签名
let sig = signature(message, &private_key); //[U8,64]
//private_key
println!("private_key: {:?} ", private_key.to_vec());
println!("private_key_len :{:? }", private_key.len());
// public_key
println!("public_key :{:?}", public_key.to_vec());
println!("public_key_len :{:?}", public_key.len());
//signature
println!("signature:{:?}", sig.to_vec());
println!("signature_len:{:?}", sig.len());
// verify
println!("验证是否成功:{:?} ",verify(message, &public_key, &sig));
}
private_key: [38, 39, 246, 133, 151, 21, 173, 29, 210, 148, 221, 196, 118, 25, 57, 49, 241, 173, 181, 88, 240, 147, 151, 50, 25, 43, 209, 192, 253, 22, 142, 78, 93, 109, 35,
107, 82, 209, 142, 58, 182, 214, 7, 47, 182, 228, 199, 212, 107, 213, 154, 217, 204, 25, 71, 38, 95, 0, 183, 32, 250, 44, 143, 102]
private_key_len :64
public_key :[93, 109, 35, 107, 82, 209, 142, 58, 182, 214, 7, 47, 182, 228, 199, 212, 107, 213, 154, 217, 204, 25, 71, 38, 95, 0, 183, 32, 250, 44, 143, 102]
public_key_len :32
signature:[163, 41, 56, 4, 173, 251, 241, 219, 149, 58, 146, 122, 98, 42, 27, 108, 25, 3, 130, 238, 94, 244, 235, 181, 70, 68, 226, 117, 98, 88, 135, 182, 110, 110, 122, 203
, 190, 66, 6, 139, 6, 242, 94, 98, 107, 99, 144, 208, 145, 218, 120, 236, 223, 60, 87, 19, 245, 249, 177, 246, 212, 160, 10, 10]
signature_len:64
验证是否成功:true