Просмотр исходного кода

sdk: Add poseidon utility function and ContractId derivation.

parazyd 3 лет назад
Родитель
Сommit
aa49a4c650

+ 0 - 60
src/crypto/contract_id.rs

@@ -1,60 +0,0 @@
-/* This file is part of DarkFi (https://dark.fi)
- *
- * Copyright (C) 2020-2022 Dyne.org foundation
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- */
-
-use darkfi_serial::{SerialDecodable, SerialEncodable};
-use pasta_curves::{group::ff::PrimeField, pallas};
-
-use super::{
-    keypair::{PublicKey, SecretKey},
-    util::poseidon_hash,
-};
-
-/// Contract ID used to reference smart contracts on the ledger.
-#[repr(C)]
-#[derive(Debug, Copy, Clone, SerialEncodable, SerialDecodable)]
-pub struct ContractId(pallas::Base);
-
-impl ContractId {
-    pub fn new(contract_id: pallas::Base) -> Self {
-        Self(contract_id)
-    }
-
-    pub fn inner(&self) -> pallas::Base {
-        self.0
-    }
-
-    pub fn to_bytes(&self) -> [u8; 32] {
-        self.0.to_repr()
-    }
-}
-
-impl std::fmt::Display for ContractId {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        // base58 encoding
-        let contractid: String = bs58::encode(self.0.to_repr()).into_string();
-        write!(f, "{}", contractid)
-    }
-}
-
-/// Derive a ContractId given a secret deploy key.
-pub fn derive_contract_id(deploy_key: SecretKey) -> ContractId {
-    let public_key = PublicKey::from_secret(deploy_key);
-    let (x, y) = public_key.xy();
-    let hash = poseidon_hash::<2>([x, y]);
-    ContractId(hash)
-}

+ 10 - 0
src/sdk/src/crypto/contract_id.rs

@@ -19,12 +19,22 @@
 use darkfi_serial::{serialize, SerialDecodable, SerialEncodable};
 use pasta_curves::{group::ff::PrimeField, pallas};
 
+use super::{poseidon_hash, PublicKey, SecretKey};
+
 /// ContractId represents an on-chain identifier for a certain
 /// smart contract.
 #[derive(Copy, Clone, Debug, Eq, PartialEq, SerialEncodable, SerialDecodable)]
 pub struct ContractId(pallas::Base);
 
 impl ContractId {
+    /// Derive a contract ID from a `SecretKey` (deploy key)
+    pub fn derive(deploy_key: SecretKey) -> Self {
+        let public_key = PublicKey::from_secret(deploy_key);
+        let (x, y) = public_key.xy();
+        let hash = poseidon_hash::<2>([x, y]);
+        Self(hash)
+    }
+
     /// Get the inner `pallas::Base` element.
     pub fn inner(&self) -> pallas::Base {
         self.0

+ 1 - 0
src/sdk/src/crypto/mod.rs

@@ -32,6 +32,7 @@ pub mod constants;
 
 /// Miscellaneous utilities
 pub mod util;
+pub use util::poseidon_hash;
 
 /// Keypairs, secret keys, and public keys
 pub mod keypair;

+ 7 - 0
src/sdk/src/crypto/util.rs

@@ -16,6 +16,7 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
+use halo2_gadgets::poseidon::primitives as poseidon;
 use pasta_curves::{arithmetic::FieldExt, group::ff::PrimeField, pallas};
 
 /// Hash `a` and `b` together with a prefix `persona` and return a `pallas::Scalar`
@@ -35,3 +36,9 @@ pub fn hash_to_scalar(persona: &[u8], a: &[u8], b: &[u8]) -> pallas::Scalar {
 pub fn mod_r_p(x: pallas::Base) -> pallas::Scalar {
     pallas::Scalar::from_repr(x.to_repr()).unwrap()
 }
+
+/// Wrapper around poseidon in `halo2_gadgets`
+pub fn poseidon_hash<const N: usize>(messages: [pallas::Base; N]) -> pallas::Base {
+    poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<N>, 3, 2>::init()
+        .hash(messages)
+}