Răsfoiți Sursa

sdk: Port Keypair and Schnorr.

parazyd 3 ani în urmă
părinte
comite
e98196baa2

+ 6 - 0
src/sdk/Cargo.toml

@@ -8,6 +8,9 @@ repository = "https://github.com/darkrenaissance/darkfi"
 license = "AGPL-3.0-only"
 license = "AGPL-3.0-only"
 edition = "2021"
 edition = "2021"
 
 
+[lib]
+doctest = false
+
 [dependencies.darkfi-serial]
 [dependencies.darkfi-serial]
 path = "../serial"
 path = "../serial"
 features = [
 features = [
@@ -23,10 +26,12 @@ thiserror = "1.0.37"
 bs58 = "0.4.0"
 bs58 = "0.4.0"
 
 
 # Cryptography
 # Cryptography
+blake2b_simd = "1.0.0"
 blake3 = "1.3.1"
 blake3 = "1.3.1"
 halo2_gadgets = "0.2.0"
 halo2_gadgets = "0.2.0"
 incrementalmerkletree = "0.3.0"
 incrementalmerkletree = "0.3.0"
 pasta_curves = "0.4.0"
 pasta_curves = "0.4.0"
+rand_core = "0.6.4"
 
 
 # Misc
 # Misc
 lazy_static = "1.4.0"
 lazy_static = "1.4.0"
@@ -34,4 +39,5 @@ subtle = "2.4.1"
 
 
 [dev-dependencies]
 [dev-dependencies]
 halo2_proofs = "0.2.0"
 halo2_proofs = "0.2.0"
+halo2_gadgets = {version = "0.2.0", features = ["test-dependencies"]}
 rand = "0.8.5"
 rand = "0.8.5"

+ 178 - 0
src/sdk/src/crypto/keypair.rs

@@ -0,0 +1,178 @@
+/* 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 core::str::FromStr;
+
+use darkfi_serial::{SerialDecodable, SerialEncodable};
+use halo2_gadgets::ecc::chip::FixedPoint;
+use pasta_curves::{
+    arithmetic::CurveAffine,
+    group::{
+        ff::{Field, PrimeField},
+        Curve, GroupEncoding,
+    },
+    pallas,
+};
+use rand_core::{CryptoRng, RngCore};
+
+use super::{constants::NullifierK, util::mod_r_p};
+use crate::error::ContractError;
+
+/// Keypair structure holding a `SecretKey` and its respective `PublicKey`
+#[derive(Copy, Clone, PartialEq, Eq, Debug, SerialEncodable, SerialDecodable)]
+pub struct Keypair {
+    pub secret: SecretKey,
+    pub public: PublicKey,
+}
+
+impl Keypair {
+    /// Instantiate a new `Keypair` given a `SecretKey`
+    pub fn new(secret: SecretKey) -> Self {
+        Self { secret, public: PublicKey::from_secret(secret) }
+    }
+
+    /// Generate a new `Keypair` object given a source of randomness
+    pub fn random(rng: &mut (impl CryptoRng + RngCore)) -> Self {
+        Self::new(SecretKey::random(rng))
+    }
+}
+
+/// Structure holding a secret key, wrapping a `pallas::Base` element.
+#[derive(Copy, Clone, PartialEq, Eq, Debug, SerialEncodable, SerialDecodable)]
+pub struct SecretKey(pallas::Base);
+
+impl SecretKey {
+    /// Get the inner object wrapped by `SecretKey`
+    pub fn inner(&self) -> pallas::Base {
+        self.0
+    }
+
+    /// Generate a new `SecretKey` given a source of randomness
+    pub fn random(rng: &mut (impl CryptoRng + RngCore)) -> Self {
+        Self(pallas::Base::random(rng))
+    }
+
+    /// Instantiate a `SecretKey` given 32 bytes. Returns an error
+    /// if the representation is noncanonical.
+    pub fn from_bytes(bytes: [u8; 32]) -> Result<Self, ContractError> {
+        match pallas::Base::from_repr(bytes).into() {
+            Some(k) => Ok(Self(k)),
+            None => Err(ContractError::IoError("Could not convert bytes to SecretKey".to_string())),
+        }
+    }
+}
+
+impl From<pallas::Base> for SecretKey {
+    fn from(x: pallas::Base) -> Self {
+        Self(x)
+    }
+}
+
+impl FromStr for SecretKey {
+    type Err = ContractError;
+
+    /// Tries to create a `SecretKey` object from a base58 encoded string.
+    fn from_str(enc: &str) -> Result<Self, Self::Err> {
+        let decoded = bs58::decode(enc).into_vec()?;
+        if decoded.len() != 32 {
+            return Err(Self::Err::IoError(
+                "Failed decoding SecretKey from bytes, len is not 32".to_string(),
+            ))
+        }
+
+        Self::from_bytes(decoded.try_into().unwrap())
+    }
+}
+
+impl core::fmt::Display for SecretKey {
+    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
+        let disp: String = bs58::encode(self.0.to_repr()).into_string();
+        write!(f, "{}", disp)
+    }
+}
+
+/// Structure holding a public key, wrapping a `pallas::Point` element.
+#[derive(Copy, Clone, PartialEq, Eq, Debug, SerialEncodable, SerialDecodable)]
+pub struct PublicKey(pallas::Point);
+
+impl PublicKey {
+    /// Get the inner object wrapped by `PublicKey`
+    pub fn inner(&self) -> pallas::Point {
+        self.0
+    }
+
+    /// Derive a new `PublicKey` object given a `SecretKey`
+    pub fn from_secret(s: SecretKey) -> Self {
+        let p = NullifierK.generator() * mod_r_p(s.inner());
+        Self(pallas::Point::from(p))
+    }
+
+    /// Instantiate a `PublicKey` given 32 bytes. Returns an error
+    /// if the representation is noncanonical.
+    pub fn from_bytes(bytes: [u8; 32]) -> Result<Self, ContractError> {
+        match pallas::Point::from_bytes(&bytes).into() {
+            Some(k) => Ok(Self(k)),
+            None => Err(ContractError::IoError("Could not convert bytes to PublicKey".to_string())),
+        }
+    }
+
+    /// Fetch the `x` coordinate of this `PublicKey`
+    pub fn x(&self) -> pallas::Base {
+        *self.0.to_affine().coordinates().unwrap().x()
+    }
+
+    /// Fetch the `y` coordinate of this `PublicKey`
+    pub fn y(&self) -> pallas::Base {
+        *self.0.to_affine().coordinates().unwrap().y()
+    }
+
+    /// Fetch the `x` and `y` coordinates of this `PublicKey` as a tuple
+    pub fn xy(&self) -> (pallas::Base, pallas::Base) {
+        let coords = self.0.to_affine().coordinates().unwrap();
+        (*coords.x(), *coords.y())
+    }
+}
+
+impl From<pallas::Point> for PublicKey {
+    fn from(x: pallas::Point) -> Self {
+        Self(x)
+    }
+}
+
+impl FromStr for PublicKey {
+    type Err = ContractError;
+
+    /// Tries to create a `PublicKey` object from a base58 encoded string.
+    fn from_str(enc: &str) -> Result<Self, Self::Err> {
+        let decoded = bs58::decode(enc).into_vec()?;
+        if decoded.len() != 32 {
+            return Err(Self::Err::IoError(
+                "Failed decoding PublicKey from bytes, len is not 32".to_string(),
+            ))
+        }
+
+        Self::from_bytes(decoded.try_into().unwrap())
+    }
+}
+
+impl core::fmt::Display for PublicKey {
+    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
+        let disp: String = bs58::encode(self.0.to_bytes()).into_string();
+        write!(f, "{}", disp)
+    }
+}

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

@@ -30,6 +30,13 @@
 /// Cryptographic constants
 /// Cryptographic constants
 pub mod constants;
 pub mod constants;
 
 
+/// Miscellaneous utilities
+pub mod util;
+
+/// Keypairs, secret keys, and public keys
+pub mod keypair;
+pub use keypair::{Keypair, PublicKey, SecretKey};
+
 /// Contract ID definitions and methods
 /// Contract ID definitions and methods
 pub mod contract_id;
 pub mod contract_id;
 pub use contract_id::ContractId;
 pub use contract_id::ContractId;
@@ -44,3 +51,6 @@ pub use nullifier::Nullifier;
 
 
 /// Pedersen commitment utilities
 /// Pedersen commitment utilities
 pub mod pedersen;
 pub mod pedersen;
+
+/// Schnorr signature traits
+pub mod schnorr;

+ 100 - 0
src/sdk/src/crypto/schnorr.rs

@@ -0,0 +1,100 @@
+/* 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 halo2_gadgets::ecc::chip::FixedPoint;
+use pasta_curves::{
+    group::{ff::Field, Group, GroupEncoding},
+    pallas,
+};
+use rand_core::{CryptoRng, RngCore};
+
+use super::{
+    constants::{NullifierK, DRK_SCHNORR_DOMAIN},
+    util::{hash_to_scalar, mod_r_p},
+    PublicKey, SecretKey,
+};
+
+/// Schnorr signature with a commit and response
+#[derive(Debug, Clone, Copy, Eq, PartialEq, SerialEncodable, SerialDecodable)]
+pub struct Signature {
+    commit: pallas::Point,
+    response: pallas::Scalar,
+}
+
+impl Signature {
+    /// Return a dummy identity `Signature`
+    pub fn dummy() -> Self {
+        Self { commit: pallas::Point::identity(), response: pallas::Scalar::zero() }
+    }
+}
+
+/// Trait for secret keys that implements a signature creation
+pub trait SchnorrSecret {
+    /// Sign a given message, using `rng` as source of randomness.
+    fn sign(&self, rng: &mut (impl CryptoRng + RngCore), message: &[u8]) -> Signature;
+}
+
+/// Trait for public keys that implements a signature verification
+pub trait SchnorrPublic {
+    /// Verify a given message is valid given a signature.
+    fn verify(&self, message: &[u8], signature: &Signature) -> bool;
+}
+
+// ===================================================================
+// Schnorr signature trait implementations for the stuff in keypair.rs
+// ===================================================================
+impl SchnorrSecret for SecretKey {
+    fn sign(&self, rng: &mut (impl CryptoRng + RngCore), message: &[u8]) -> Signature {
+        let mask = pallas::Scalar::random(rng);
+        let commit = NullifierK.generator() * mask;
+
+        let challenge = hash_to_scalar(DRK_SCHNORR_DOMAIN, &commit.to_bytes(), message);
+        let response = mask + challenge * mod_r_p(self.inner());
+
+        Signature { commit, response }
+    }
+}
+
+impl SchnorrPublic for PublicKey {
+    fn verify(&self, message: &[u8], signature: &Signature) -> bool {
+        let challenge = hash_to_scalar(DRK_SCHNORR_DOMAIN, &signature.commit.to_bytes(), message);
+        NullifierK.generator() * signature.response - self.inner() * challenge == signature.commit
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use darkfi_serial::{deserialize, serialize};
+    use rand::rngs::OsRng;
+
+    #[test]
+    fn test_schnorr_signature() {
+        let secret = SecretKey::random(&mut OsRng);
+        let message: &[u8] = b"aaaahhhh i'm signiiinngg";
+        let signature = secret.sign(&mut OsRng, message);
+        let public = PublicKey::from_secret(secret);
+        assert!(public.verify(message, &signature));
+
+        // Check out if it's also fine with serialization
+        let ser = serialize(&signature);
+        let de = deserialize(&ser).unwrap();
+        assert!(public.verify(message, &de));
+    }
+}

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

@@ -0,0 +1,37 @@
+/* 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 pasta_curves::{arithmetic::FieldExt, group::ff::PrimeField, pallas};
+
+/// Hash `a` and `b` together with a prefix `persona` and return a `pallas::Scalar`
+/// element from the digest.
+pub fn hash_to_scalar(persona: &[u8], a: &[u8], b: &[u8]) -> pallas::Scalar {
+    let mut hasher = blake2b_simd::Params::new().hash_length(64).personal(persona).to_state();
+    hasher.update(a);
+    hasher.update(b);
+    let ret = hasher.finalize();
+    pallas::Scalar::from_bytes_wide(ret.as_array())
+}
+
+/// Converts from pallas::Base to pallas::Scalar (aka $x \pmod{r_\mathbb{P}}$).
+///
+/// This requires no modular reduction because Pallas' base field is smaller than its
+/// scalar field.
+pub fn mod_r_p(x: pallas::Base) -> pallas::Scalar {
+    pallas::Scalar::from_repr(x.to_repr()).unwrap()
+}

+ 37 - 39
src/sdk/src/db.rs

@@ -1,3 +1,21 @@
+/* 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::Encodable;
 use darkfi_serial::Encodable;
 
 
 use super::{
 use super::{
@@ -7,7 +25,6 @@ use super::{
 };
 };
 
 
 pub type DbHandle = u32;
 pub type DbHandle = u32;
-type TxHandle = u32;
 
 
 /// Only deploy() can call this. Creates a new database instance for this contract.
 /// Only deploy() can call this. Creates a new database instance for this contract.
 ///
 ///
@@ -16,7 +33,6 @@ type TxHandle = u32;
 ///     db_init(db_name) -> DbHandle
 ///     db_init(db_name) -> DbHandle
 /// ```
 /// ```
 pub fn db_init(contract_id: ContractId, db_name: &str) -> GenericResult<DbHandle> {
 pub fn db_init(contract_id: ContractId, db_name: &str) -> GenericResult<DbHandle> {
-    #[cfg(target_arch = "wasm32")]
     unsafe {
     unsafe {
         let mut len = 0;
         let mut len = 0;
         let mut buf = vec![];
         let mut buf = vec![];
@@ -35,13 +51,9 @@ pub fn db_init(contract_id: ContractId, db_name: &str) -> GenericResult<DbHandle
 
 
         return Ok(ret as u32)
         return Ok(ret as u32)
     }
     }
-
-    #[cfg(not(target_arch = "wasm32"))]
-    unimplemented!()
 }
 }
 
 
 pub fn db_lookup(contract_id: ContractId, db_name: &str) -> GenericResult<DbHandle> {
 pub fn db_lookup(contract_id: ContractId, db_name: &str) -> GenericResult<DbHandle> {
-    #[cfg(target_arch = "wasm32")]
     unsafe {
     unsafe {
         let mut len = 0;
         let mut len = 0;
         let mut buf = vec![];
         let mut buf = vec![];
@@ -60,9 +72,6 @@ pub fn db_lookup(contract_id: ContractId, db_name: &str) -> GenericResult<DbHand
 
 
         return Ok(ret as u32)
         return Ok(ret as u32)
     }
     }
-
-    #[cfg(not(target_arch = "wasm32"))]
-    unimplemented!()
 }
 }
 
 
 /// Everyone can call this. Will read a key from the key-value store.
 /// Everyone can call this. Will read a key from the key-value store.
@@ -71,34 +80,28 @@ pub fn db_lookup(contract_id: ContractId, db_name: &str) -> GenericResult<DbHand
 ///     value = db_get(db_handle, key);
 ///     value = db_get(db_handle, key);
 /// ```
 /// ```
 pub fn db_get(db_handle: DbHandle, key: &[u8]) -> GenericResult<Option<Vec<u8>>> {
 pub fn db_get(db_handle: DbHandle, key: &[u8]) -> GenericResult<Option<Vec<u8>>> {
-    #[cfg(target_arch = "wasm32")]
-    {
-        let mut len = 0;
-        let mut buf = vec![];
-        len += db_handle.encode(&mut buf)?;
-        len += key.to_vec().encode(&mut buf)?;
-
-        let ret = unsafe { db_get_(buf.as_ptr(), len as u32) };
-
-        if ret < 0 {
-            match ret {
-                -1 => return Err(ContractError::CallerAccessDenied),
-                -2 => return Err(ContractError::DbGetFailed),
-                -3 => return Ok(None),
-                _ => unimplemented!(),
-            }
+    let mut len = 0;
+    let mut buf = vec![];
+    len += db_handle.encode(&mut buf)?;
+    len += key.to_vec().encode(&mut buf)?;
+
+    let ret = unsafe { db_get_(buf.as_ptr(), len as u32) };
+
+    if ret < 0 {
+        match ret {
+            -1 => return Err(ContractError::CallerAccessDenied),
+            -2 => return Err(ContractError::DbGetFailed),
+            -3 => return Ok(None),
+            _ => unimplemented!(),
         }
         }
-
-        let obj = ret as u32;
-        let obj_size = get_object_size(obj);
-        let mut buf = vec![0u8; obj_size as usize];
-        get_object_bytes(&mut buf, obj);
-
-        Ok(Some(buf))
     }
     }
 
 
-    #[cfg(not(target_arch = "wasm32"))]
-    unimplemented!()
+    let obj = ret as u32;
+    let obj_size = get_object_size(obj);
+    let mut buf = vec![0u8; obj_size as usize];
+    get_object_bytes(&mut buf, obj);
+
+    Ok(Some(buf))
 }
 }
 
 
 /// Only update() can call this. Set a value within the transaction.
 /// Only update() can call this. Set a value within the transaction.
@@ -108,7 +111,6 @@ pub fn db_get(db_handle: DbHandle, key: &[u8]) -> GenericResult<Option<Vec<u8>>>
 /// ```
 /// ```
 pub fn db_set(db_handle: DbHandle, key: &[u8], value: &[u8]) -> GenericResult<()> {
 pub fn db_set(db_handle: DbHandle, key: &[u8], value: &[u8]) -> GenericResult<()> {
     // Check entry for tx_handle is not None
     // Check entry for tx_handle is not None
-    #[cfg(target_arch = "wasm32")]
     unsafe {
     unsafe {
         let mut len = 0;
         let mut len = 0;
         let mut buf = vec![];
         let mut buf = vec![];
@@ -123,12 +125,8 @@ pub fn db_set(db_handle: DbHandle, key: &[u8], value: &[u8]) -> GenericResult<()
             _ => unreachable!(),
             _ => unreachable!(),
         }
         }
     }
     }
-
-    #[cfg(not(target_arch = "wasm32"))]
-    unimplemented!()
 }
 }
 
 
-#[cfg(target_arch = "wasm32")]
 extern "C" {
 extern "C" {
     fn db_init_(ptr: *const u8, len: u32) -> i32;
     fn db_init_(ptr: *const u8, len: u32) -> i32;
     fn db_lookup_(ptr: *const u8, len: u32) -> i32;
     fn db_lookup_(ptr: *const u8, len: u32) -> i32;

+ 6 - 0
src/sdk/src/error.rs

@@ -140,3 +140,9 @@ impl From<std::io::Error> for ContractError {
         Self::IoError(format!("{}", err))
         Self::IoError(format!("{}", err))
     }
     }
 }
 }
+
+impl From<bs58::decode::Error> for ContractError {
+    fn from(err: bs58::decode::Error) -> Self {
+        Self::IoError(format!("{}", err))
+    }
+}

+ 19 - 2
src/sdk/src/merkle.rs

@@ -1,10 +1,27 @@
+/* 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::Encodable;
 use darkfi_serial::Encodable;
 
 
 use super::{
 use super::{
-    crypto::{ContractId, MerkleNode},
+    crypto::MerkleNode,
     db::DbHandle,
     db::DbHandle,
     error::{ContractError, GenericResult},
     error::{ContractError, GenericResult},
-    util::{get_object_bytes, get_object_size},
 };
 };
 
 
 pub fn merkle_add(
 pub fn merkle_add(

+ 18 - 0
src/sdk/src/tx.rs

@@ -1,3 +1,21 @@
+/* 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 darkfi_serial::{SerialDecodable, SerialEncodable};
 
 
 use super::crypto::ContractId;
 use super::crypto::ContractId;

+ 21 - 26
src/sdk/src/util.rs

@@ -1,49 +1,44 @@
+/* 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 super::error::ContractError;
 use super::error::ContractError;
 
 
 pub fn set_return_data(data: &[u8]) -> Result<(), ContractError> {
 pub fn set_return_data(data: &[u8]) -> Result<(), ContractError> {
-    #[cfg(target_arch = "wasm32")]
     unsafe {
     unsafe {
         return match set_return_data_(data.as_ptr(), data.len() as u32) {
         return match set_return_data_(data.as_ptr(), data.len() as u32) {
             0 => Ok(()),
             0 => Ok(()),
             errcode => Err(ContractError::from(errcode)),
             errcode => Err(ContractError::from(errcode)),
         }
         }
     }
     }
-
-    #[cfg(not(target_arch = "wasm32"))]
-    unimplemented!();
 }
 }
 
 
 pub fn put_object_bytes(data: &[u8]) -> i64 {
 pub fn put_object_bytes(data: &[u8]) -> i64 {
-    #[cfg(target_arch = "wasm32")]
-    unsafe {
-        return put_object_bytes_(data.as_ptr(), data.len() as u32)
-    }
-
-    #[cfg(not(target_arch = "wasm32"))]
-    unimplemented!();
+    unsafe { return put_object_bytes_(data.as_ptr(), data.len() as u32) }
 }
 }
 
 
 pub fn get_object_bytes(data: &mut [u8], object_index: u32) -> i64 {
 pub fn get_object_bytes(data: &mut [u8], object_index: u32) -> i64 {
-    #[cfg(target_arch = "wasm32")]
-    {
-        unsafe { return get_object_bytes_(data.as_mut_ptr(), object_index as u32) }
-    }
-
-    #[cfg(not(target_arch = "wasm32"))]
-    unimplemented!();
+    unsafe { return get_object_bytes_(data.as_mut_ptr(), object_index as u32) }
 }
 }
 
 
 pub fn get_object_size(object_index: u32) -> i64 {
 pub fn get_object_size(object_index: u32) -> i64 {
-    #[cfg(target_arch = "wasm32")]
-    unsafe {
-        return get_object_size_(object_index as u32)
-    }
-
-    #[cfg(not(target_arch = "wasm32"))]
-    unimplemented!();
+    unsafe { return get_object_size_(object_index as u32) }
 }
 }
 
 
-#[cfg(target_arch = "wasm32")]
 extern "C" {
 extern "C" {
     fn set_return_data_(ptr: *const u8, len: u32) -> i64;
     fn set_return_data_(ptr: *const u8, len: u32) -> i64;
     fn put_object_bytes_(ptr: *const u8, len: u32) -> i64;
     fn put_object_bytes_(ptr: *const u8, len: u32) -> i64;