您正在查看: EOS-开源推荐 分类下的文章

MPC安全多方计算

隐私问题是目前区块链技术所要解决的其中一重要问题,隐私保护不仅在区块链领域成为了重点研究内容之一,而且近几年不断出现的数据隐私泄露问题,也让公众对隐私保护有日益深入的认知。

PlatON基于安全多方计算密码学算法实现一种隐私合约的解决方案,主要思想是将隐私计算算法通过合约进行发布,并由隐私保护需求的数据提供方和计算节点配合执行MPC协议,以实现数据的协同计算。

安全多方计算介绍

安全多方计算,英文全称为Secure Multi-Party Computation,简称MPC。它指的是用户在无需进行数据归集的情况下,完成数据协同计算,同时保护数据所有方的原始数据隐私。具体来说,有n个计算参与方,分别持有私有数据 共同计算既定函数

计算完成,得到正确计算结果y,且参与各方除了自己的输入数据和输出结果外,无法获知任何额外有效信息。
MPC协议满足的基本性质是:

  • 输入隐私性: 协议执行过程中的中间数据不会泄露双方原始数据的相关信息;
  • 健壮性: 协议执行过程中,参与方不会输出不正确的结果。

构建通用MPC协议的典型范式之一是基于姚期智提出的针对两方计算的加密电路方法,并由Beaver、Micali 和Rogaway 进一步扩展到多方计算。目前MPC相关的协议或算法有Garbled Circuit、Oblivious Transfer、Secret Sharing、BGW、GMW、BMR等,同时工程实现上也有如SPDZ、LEGO、Sharemind、Fairplay等不同的安全多方计算框架出来。典型的安全两方计算所使用的协议为加密电路(Garbled Circuit, GC)和不经意传输(Oblivious Transfer, OT)。

Garbled Circuit

关于Garbled Circuit原理,可进一步参考此页面所做的解释。

目前已经有很多对加密电路进行优化的方案。包括Free-XOR 技术,这意味着XOR 门几乎无需加密,row reduction 和half gate技术,将每个AND门所需要的密文从4个降为2个。最近使用认证加密电路的研究结果实现了针对两方和多方恶意敌手模型下非常有效的协议。

若有兴趣对Garbled Circuit的理论知识作更深入的了解,可参考此论文。

Oblivious Transfer

Oblivious Transfer,中文称为不经意传输,通常简写为OT,它指的是发送者从一个值集合中向接收者发送单个值的问题,这里发送者无法知道发送的是哪一个值,而且接收者也不能获知除了接收值之外的其它任何值。形式化描述为:发送者有由N个值组成的集合,接收者有索引协议执行完成,接收者只知道不知道,这里并且发送者不知道i,这称为1-out-of-N Oblivious Transfer。

对于N=2,即为1-out-of-2 Oblivious Transfer,接收者在计算加密电路之前,首先根据自己的输入数据获得与之对应的标签,由于标签是发送者定义的,因此接收者与发送者之间执行此OT协议。接收者按照其输入的每个比特,以σ=0/1为输入,发送者以标签m0、m1为输入。协议执行完成,接收者获得标签mσ。图7为1-out-of-2 OT的示意图。协议执行的过程中,满足以下性质:

  • 发送者不可获知接收者选择的是哪个标签;
  • 接收者无法知道另一个标签

两方安全计算的工作原理

两方计算的实现过程为:

两个计算参与方Alice和Bob,想共同计算
这里s为Alice所拥有的数据,t为Bob所拥有的数据,f为计算逻辑。首先,Alice将f转换为相应的布尔电路C,其中C的每个门都有一个真值表表示门的输入输出。然后,Alice对真值表进行加密处理,得到加密电路同时,Alice也对其输入进行加密,然后将加密后的输入与加密电路一同发送给Bob。那么此时Bob就拥有了和Alice的加密输入(对应于Alice输入的标签),但却未被告知Alice的加密过程,因此Bob就无法获知该如何使用自己的输入。这时,Bob通过与Alice之间执行1-out-of-2 Oblivious Transfer协议来获得加密输入(对应于自己输入的标签)。之后,Bob使用两方的加密输入对加密电路逐个门进行解密,获得电路计算结果。

总体分为如下五个步骤,其详细过程解释如下:

1. 布尔电路生成

假设是需要安全计算的函数,将此函数转换为布尔电路满足对任意理论上任意函数均可表示成布尔电路。布尔电路的格式如图1所示:

图2: 函数转换为布尔电路

2. 加密电路生成

Alice将函数转换为布尔电路后,将电路的每个门表示成如图2所示的真值表,接着通过加密这些真值表将转化为加密电路

图3: 将电路中的每个门表示成真值表

PlatON中的安全多方计算

安全多方计算为PlatON实现隐私数据的协同计算提供了根本性的技术手段,在PlatON中结合MPC实现隐私合约,为具有多方参与数据作为输入的应用提供隐私保护,实现真正的隐私计算。

PlatON的两方安全计算架构如下:

PlatON的隐私合约同样支持高级语言编程,但不是编译成庞大的布尔电路文件,而是编译成更高效的LLVM IR字节码,并部署到PlatON网络上,在MPC计算节点内置的MPC虚拟机中以JIT方式执行。隐私合约的输入数据保存在数据节点本地,由数据节点在链下以安全多方计算方式进行隐私计算,并提交计算结果到链上。

PlatON会持续优化当前已实现版本的MPC性能,并实现更先进的MPC协议,在以下几个方面进行改进:

  • 结合同态加密(HE)来降低MPC的通信复杂度
  • 从两方安全计算实现到三方以上的多方计算,以满足更加复杂多样化的应用场景

转载自 https://devdocs.platon.network/docs/zh-CN/Secure_Multi_Party_Computation/

开源代码:https://github.com/PlatONnetwork

HD钱包地址生成JavaScript库

支持的加密货币

BTC,ETH,BCH,SLP,BSV,DASH,LTC,DOGE,EOS,XRP,NAV ,STRAT

开源库地址:https://github.com/lpopo0856/cryptohdwallet

基于 EOS 公钥加密,私钥解密示例

eos-crypto-java 使用指南

源码:https://github.com/yanjunli/eos-crypto-java

eos-crypto-java 目前可以支持 基于 ECC+AES 的加解密方式。

在本压缩包中,包含基于jdk1.5 打好的jar 包。

要求

jdk 1.5+

基于 EOS 公钥加密,私钥解密示例

        String privateKey =  "5KTZYCDdcfNrmEpcf97SJBCtToZjYHjHm8tqTWvzUbsUJgkxcfk";
        EosPrivateKey eosPrivateKey = new EosPrivateKey(privateKey);
        EosPublicKey  eosPublicKey = eosPrivateKey.getPublicKey();
        // 转换成 EC privatekey
        ECPrivateKey ecPrivateKey = eosPrivateKey.getECPrivateKey();
        ECPublicKey ecPublicKey = eosPublicKey.getECPublicKey();

        byte[] plaindata = "{\"age\": 1,\"12345\":\"24qqwazzxdtttdxkaskjewuizckczxnlsdosasda4!!!@#$$%^&&*(()(^#\"}".getBytes("utf8");

        System.out.println("加密原文:" + new String(plaindata));

        byte[] encryptdata = ECCUtil.publicEncrypt(plaindata,ecPublicKey);

        System.out.println("加密后密文:" + HexUtils.toHex(encryptdata));

        plaindata = ECCUtil.privateDecrypt(encryptdata,ecPrivateKey);

        System.out.println("解密后原文: "+ new String(plaindata));

基于ECC+AES 双向验证 加解密示例

/**
*
* sender  发起方密钥对
*
* EOS8g1u3ktAGHs4QsVp9aeaWNebFLtprQHwpaSjegx6iEuoTNhjXU
* 5KTZYCDdcfNrmEpcf97SJBCtToZjYHjHm8tqTWvzUbsUJgkxcfk
*
* receiver 接收方一密钥对
*
* EOS7ez2gagfoXw9XdW3kRx3EsCoWvupGR6u6ZJhFPEe9Q12V8JgUL
* 5JUrqxYcssR9LLVtWDeQcc9HCX4FEqBG7d9GW6t7mvmB1rUuZr9
*
* receiver 接收方二 密钥对
* EOS5WMHqw6jDDBPBm7JXTHemAwtSo2tp93pRysJMRhiT1zUYb24vL
* 5HrcVeuHHNwHsivrMoJ9XvU6EM7Q2wQ2ECiy8GeoiuamhNiSuZq
*/

// 1.  调用钱包获取 发送方私钥
  String senderPrivateKey =  "5KTZYCDdcfNrmEpcf97SJBCtToZjYHjHm8tqTWvzUbsUJgkxcfk";
  EosPrivateKey senderECPrivateKey = new EosPrivateKey(senderPrivateKey);
//        EosPublicKey senderECPublicKey = new EosPublicKey(senderPublicKey);
        // 2.  根据私钥 生成公钥。 或者直接根据公钥 调用钱包获取私钥。 都可以。
  EosPublicKey senderECPublicKey = senderECPrivateKey.getPublicKey();

  String senderPublicKey = senderECPublicKey.toString();
  /**
   * 调用钱包获取 接收方私钥   获取公私钥方式 根据需求确定。
   *  1. 可以根据公钥,从钱包里获取私钥
   *  2. 也可以直接从钱包里取出私钥,反向生成公钥
   *  
   *  实际业务场景,发起方只会有接收方公钥,并没有接收方私钥. 
   *  此时 可以通过 new EosPublicKey(receiverPublicKey) 方式 生成EosPublicKey 对象。
   */
  String receiverPrivateKey = "5JUrqxYcssR9LLVtWDeQcc9HCX4FEqBG7d9GW6t7mvmB1rUuZr9";
  EosPrivateKey receiverECPrivateKey = new EosPrivateKey(receiverPrivateKey);
  EosPublicKey receiverECPublicKey = receiverECPrivateKey.getPublicKey();
  String receiverPublicKey = receiverECPublicKey.toString();
  //        String receiverPublicKey =  "EOS7ez2gagfoXw9XdW3kRx3EsCoWvupGR6u6ZJhFPEe9Q12V8JgUL";


  /**
   * 使用 发送者方私钥 和接收方公钥,生成 aes key, 对数据进行加密
   * nonce  为初始化向量,可以使用固定值,
   *                      也可以使用随机值,并使用私有协议。根据业务需求选择。
   */
  byte[] nonce = new byte[16];
  MTRandom random=new MTRandom();
  random.nextBytes(nonce);

  // 待加密 数据
  byte[] params = "{\"test1\": 1,\"test2\":\"24qqwazzxdtttdxkaskjewuizckczxnlsdosasda4!!!@#$$%^&&*((){}(^#\"}".getBytes("utf8");

  System.out.println("原始加密数据: " + new String(params,"utf8"));

  byte[] encrypted = new byte[0];
  try {
      encrypted = CryptUtil.encrypt(senderECPrivateKey,receiverECPublicKey,nonce,params);
  } catch (InvalidCipherTextException e) {
      e.printStackTrace();
      System.out.println("  do something!!!!");
  }

  System.out.println("加密后数据: " + new String(encrypted,"utf8"));
  try {
      byte[] plainText = CryptUtil.decrypt(receiverECPrivateKey,senderECPublicKey,nonce,encrypted);
      // 解密后数据
      System.out.println("解密后数据 :  "+new String(plainText, "utf8"));
  } catch (InvalidCipherTextException e) {
      e.printStackTrace();
      System.out.println("  do something!!!!");
  }

基于数字信封的 加解密示例


/**
         *
         * sender
         *
         * EOS8g1u3ktAGHs4QsVp9aeaWNebFLtprQHwpaSjegx6iEuoTNhjXU
         * 5KTZYCDdcfNrmEpcf97SJBCtToZjYHjHm8tqTWvzUbsUJgkxcfk
         *
         * receiver 平台公私钥对
         *
         * EOS7ez2gagfoXw9XdW3kRx3EsCoWvupGR6u6ZJhFPEe9Q12V8JgUL
         * 5JUrqxYcssR9LLVtWDeQcc9HCX4FEqBG7d9GW6t7mvmB1rUuZr9
         *
         * receiver 省侧公私钥对
         * EOS5WMHqw6jDDBPBm7JXTHemAwtSo2tp93pRysJMRhiT1zUYb24vL
         * 5HrcVeuHHNwHsivrMoJ9XvU6EM7Q2wQ2ECiy8GeoiuamhNiSuZq
         */

        // 1.  调用钱包获取 发送方私钥
        String senderPrivateKey =  "5KTZYCDdcfNrmEpcf97SJBCtToZjYHjHm8tqTWvzUbsUJgkxcfk";
        EosPrivateKey senderECPrivateKey = new EosPrivateKey(senderPrivateKey);
//        EosPublicKey senderECPublicKey = new EosPublicKey(senderPublicKey);
        // 2.  根据私钥 生成公钥。 或者直接根据公钥 调用钱包获取私钥。 都可以,看具体业务需求
        EosPublicKey senderECPublicKey = senderECPrivateKey.getPublicKey();

        String senderPublicKey = senderECPublicKey.toString();
        /**
         * 调用钱包获取 接收方私钥   获取公私钥方式 根据业务需求确定。
         *  1. 可以根据公钥,从钱包里获取私钥
         *  2. 也可以直接从钱包里取出私钥,反向生成公钥
         */
        String receiverPrivateKey = "5JUrqxYcssR9LLVtWDeQcc9HCX4FEqBG7d9GW6t7mvmB1rUuZr9";
        EosPrivateKey receiverECPrivateKey = new EosPrivateKey(receiverPrivateKey);

        EosPublicKey receiverECPublicKey = receiverECPrivateKey.getPublicKey();

        /**
         * 生成对称密钥
         */
        byte[] nonce = new byte[16];
        MTRandom random=new MTRandom();
        random.nextBytes(nonce);

        // 待加密 数据
        byte[] params = "{\"age\": 1,\"汉字\":\"为初始化向量,可以使用固定值,\",\"12345\":\"24qqwazzxdtttdxkaskjewuizckczxnlsdosasda4!!!@#$$%^&&*(()(^#\"}".getBytes("utf8");

        System.out.println("加密前原始数据: " + new String(params,"utf8"));

        // 发起方使用对称密钥,对原始数据进行加密
        byte[] encryptedData = null;
        try {
            encryptedData = CryptUtil.aesEncryptWithNOIV(nonce,params);
        } catch (InvalidCipherTextException e) {
            e.printStackTrace();
            System.out.println("  do something!!!!");
        }

        System.out.println("加密后数据: " + HexUtils.toHex(encryptedData));


        System.out.println("加密前对称密钥: " + HexUtils.toHex(nonce));

        // 发起方使用 接收方公钥,对对称密钥进行加密
        byte[] encryptedKey = null;
        try {
            encryptedKey = ECCUtil.publicEncrypt(nonce,receiverECPublicKey.getECPublicKey());
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("  do something!!!!");
        }

        System.out.println("加密后对称密钥: " + HexUtils.toHex(encryptedKey));

        // 将对称密钥加密后的数据,密文组装后,进行网络传输。
        // 组装 demo
        /**
         *    4 byte                       |      encryptedKey                 |       4 byte              | encryptedData
         *    对称密钥加密后的数据长度      |      ECC 加密后的对称秘钥           |       密文数据长度         | AES 加密后的密文
         */

        ByteBuffer bytebuffer = ByteBuffer.allocate( 4 + encryptedKey.length + 4 +encryptedData.length);
        bytebuffer.putInt(encryptedKey.length);
        bytebuffer.put(encryptedKey);
        bytebuffer.putInt(encryptedData.length);
        bytebuffer.put(encryptedData);

//        String base58encode = Base58.encode(bytebuffer.array());
//        System.out.println("base58 编码后的:   " + base58encode);

        // 进行 16 进制编码
        String hexencode = HexUtils.toHex(bytebuffer.array());

        System.out.println(" 将数字信封和密文组装后的报文 16进制格式:" + hexencode);

        System.out.println("发送方数据加密完成,可以将数据发送出去 ");

        /**
         *****************************************************  以下为接收方 代码  *************************************
         */

//        byte[] base58decode = Base58.decode(hexencode);
        byte[] hexdecode = HexUtils.toBytes(hexencode);
        ByteBuffer receiveBuffer = ByteBuffer.wrap(hexdecode);

        // 获取到对称秘钥长度
        int receivedEncryptedKeyLength = receiveBuffer.getInt();
        // 加密后的对称密钥key
        byte[] receivedEncryptKey = new byte[receivedEncryptedKeyLength];
        receiveBuffer.get(receivedEncryptKey,0,receivedEncryptedKeyLength);

        System.out.println(" 接收到的 加密后的对称密钥 :" + HexUtils.toHex(receivedEncryptKey));
        // 获取到的 密文的长度
        int contextLength = receiveBuffer.getInt();
        // 密文
        byte[] receivedEncryptContext = new byte[contextLength];
        receiveBuffer.get(receivedEncryptContext,0,contextLength);

        System.out.println(" 接收到的 密文:" + HexUtils.toHex(receivedEncryptContext));


        // 使用接收方私钥,解密对称密钥
        byte[] receiveddecryptKey = null;
        try {
            receiveddecryptKey = ECCUtil.privateDecrypt(receivedEncryptKey,receiverECPrivateKey.getECPrivateKey());
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("  do something!!!!");
        }

        System.out.println(" 解密后的对称密钥 :" + HexUtils.toHex(receiveddecryptKey));

        // 使用对称密钥,对密文进行解密

        try {
            byte[] plainText = CryptUtil.aesDecryptWithNOIV(receiveddecryptKey,receivedEncryptContext);
            // 解密后数据
            System.out.println("解密后数据 :  "+new String(plainText, "utf8"));
        } catch (InvalidCipherTextException e) {
            e.printStackTrace();
            System.out.println("  do something!!!!");
        }

Eosplayer -> eosjs的绑定层

Eosplayer是eosjs的绑定层,它基于eosjs并为应用程序层提供了更好的可用性。它既可以在node.js服务器上使用,也可以在已经安装了Scatter的浏览器或Dapp钱包中使用。

frontd releases : https://github.com/bagaking/eosplayer/releases

演示地址:http://eosplayer.kihand.com/#/

工作量证明(PoW)与EOSIO一起使用

https://www.eospow.org/
https://github.com/NedAmarril/eosiopowcoin

EOS 工作量证明硬币(POW)[1]将PoW(工作量证明)采矿时间表和调整比特币(BTC)[2] 的难度应用于EOSIO [3]令牌。

每10分钟铸造50个战俘,持续约4年,然后将一半铸造成一半。一直重复,直到有2100万个POW,与BTC完全一样。

EOS CPU和NET资源用于通过将EOS转移到eosiopowcoin来挖掘POW。每次您将EOS发送到eosiopowcoin合约账户时,该EOS的确切金额加上eosiopowcoin账户中总POW供应量的0.0025%将会被转回给您。

POW是一个完全分散的,不信任的开源项目,无需开发人员分配。每个单独的战俘都已经或将要被开采。没有给予战俘免费或预先开采。使用setupminer 操作后,任何人都可以挖掘POW 。战俘的铸造将持续到供应达到2100万为止。没有人可以阻止POW的铸造,开采或分销。合同是无钥匙的。