Mina 采用 Schnorr signature 生成签名.
输入 kp=(sk, pk), input 输出签名 sig=(s, R.x)
输入 sig, pk, msg 输出: bool
/// This function uses a cryptographic hash function to create a uniformly and
/// randomly distributed nonce. It is crucial for security that no two different
/// messages share the same nonce.
fn derive_nonce(&self, kp: &Keypair, input: &H) -> ScalarField {
let mut blake_hasher = Blake2bVar::new(32).unwrap();
let roi = input
.to_roinput()
.append_field(kp.public.point().x)
.append_field(kp.public.point().y)
.append_scalar(*kp.secret.scalar())
.append_bytes(&self.domain_param.clone().into_bytes());
blake_hasher.update(&roi.to_bytes());
let mut bytes = [0; 32];
blake_hasher
.finalize_variable(&mut bytes)
.expect("incorrect output size");
// Drop the top two bits to convert into a scalar field element
// N.B. Since the order of Pallas's scalar field p is very close to 2^m
// for some m, truncating only creates a tiny amount of bias that should
// be insignificant and better than reduction modulo p.
bytes[bytes.len() - 1] &= 0b0011_1111;
ScalarField::from_random_bytes(&bytes[..]).expect("failed to create scalar from bytes")
}
fn message_hash(&mut self, pub_key: &PubKey, rx: BaseField, input: &H) -> ScalarField {
let schnorr_input = Message::<H> {
input: input.clone(),
pub_key_x: pub_key.point().x,
pub_key_y: pub_key.point().y,
rx,
};
// Squeeze and convert from base field element to scalar field element
// Since the difference in modulus between the two fields is < 2^125, w.h.p., a
// random value from one field will fit in the other field.
ScalarField::from(self.hasher.hash(&schnorr_input).into_bigint())
}
Mina hash 主要使用 Poseidon, 主要原因应该是 Poseidon zk-friendly, 生成电路约束较(SHA256, Keccak256 ...)少.
Mina 使用下面两种, 区别是 Poseidon 参数不同. 详细请看 params.sage.
pub(crate) fn create_legacy<H: 'static + Hashable>(domain_param: H::D) -> impl Signer<H> {
Schnorr::<H> {
hasher: Box::new(mina_hasher::create_legacy::<Message<H>>(
domain_param.clone(),
)),
domain_param,
}
}
pub(crate) fn create_kimchi<H: 'static + Hashable>(domain_param: H::D) -> impl Signer<H> {
Schnorr::<H> {
hasher: Box::new(mina_hasher::create_kimchi::<Message<H>>(
domain_param.clone(),
)),
domain_param,
}
}
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!