コード例 #1
0
ファイル: ChainIdTest.cs プロジェクト: LAToken/lachain
        // mimic of VerifySignatureHashed of DefaultCrypto.cs but using different chain id
        public bool VerifySignatureHashed(byte[] messageHash, byte[] signature, byte[] publicKey, bool useNewChainId)
        {
            if (messageHash.Length != 32 || signature.Length != SignatureSize(useNewChainId))
            {
                return(false);
            }
            return(EcVerify.Benchmark(() =>
            {
                var pk = new byte[64];
                if (!Secp256K1.PublicKeyParse(pk, publicKey))
                {
                    return false;
                }

                var publicKeySerialized = new byte[33];
                if (!Secp256K1.PublicKeySerialize(publicKeySerialized, pk, Flags.SECP256K1_EC_COMPRESSED))
                {
                    throw new Exception("Cannot serialize parsed key: how did it happen?");
                }

                var parsedSig = new byte[65];
                var recId = (RestoreEncodedRecIdFromSignatureBuffer(signature) - 36) / 2 / ChainId(useNewChainId);
                if (recId < 0 || recId > 3)
                {
                    throw new Exception($"Invalid recId={recId}: : recId >= 0 && recId <= 3 ");
                }
                if (!Secp256K1.RecoverableSignatureParseCompact(parsedSig, signature.Take(64).ToArray(), recId))
                {
                    return false;
                }

                return Secp256K1.Verify(parsedSig.Take(64).ToArray(), messageHash, pk);
            }));
        }
コード例 #2
0
        public bool AddShare(int idx, Signature sigShare, out Signature?result)
        {
            result = null;
            if (idx < 0 || idx >= _publicKeySet.Count)
            {
                Logger.LogWarning($"Public key (?) is not recognized (index {idx})");
                return(false);
            }

            var pubKey = _publicKeySet[idx];

            if (_collectedShares[idx] != null)
            {
                Logger.LogWarning($"Signature share {idx} input twice");
                if (sigShare != _collectedShares[idx])
                {
                    return(false);
                }
                _collectedSharesNumber--; // to compensate increment later
            }

            if (!IsShareValid(pubKey, sigShare))
            {
                Logger.LogWarning($"Signature share {idx} is not valid: {sigShare.ToHex()}");
                return(false);
            }

            if (_collectedSharesNumber > _publicKeySet.Threshold)
            {
                result = _signature;
                return(true);
            }

            Logger.LogTrace($"Collected signature share #{idx}: {sigShare.RawSignature.ToHex()}");
            _collectedShares[idx]   = sigShare;
            _collectedSharesNumber += 1;
            if (_collectedSharesNumber <= _publicKeySet.Threshold)
            {
                return(true);
            }
            var signature = CombineBenchmark.Benchmark(() => _publicKeySet.AssembleSignature(
                                                           _collectedShares.Select((share, i) => new KeyValuePair <int, Signature>(i, share))
                                                           .Where(pair => pair.Value != null).ToArray()
                                                           ));

            if (!_publicKeySet.SharedPublicKey.ValidateSignature(signature, _dataToSign))
            {
                throw new Exception("Fatal error: all shares are valid but combined signature is not");
            }
            _signature = signature;
            result     = signature;
            return(true);
        }
コード例 #3
0
ファイル: PrivateKey.cs プロジェクト: LAToken/lachain
 public PartiallyDecryptedShare Decrypt(EncryptedShare share)
 {
     return(DecryptBenchmark.Benchmark(() =>
     {
         var h = Utils.HashToG2(share.U, share.V);
         if (!GT.Pairing(G1.Generator, share.W).Equals(GT.Pairing(share.U, h)))
         {
             throw new Exception("Invalid share!");
         }
         var ui = share.U * _x;
         return new PartiallyDecryptedShare(ui, _id, share.Id);
     }));
 }
コード例 #4
0
ファイル: PublicKey.cs プロジェクト: LAToken/lachain
 public EncryptedShare Encrypt(IRawShare rawShare)
 {
     return(EncryptBenchmark.Benchmark(() =>
     {
         var r = Fr.GetRandom();
         var u = G1.Generator * r;
         var shareBytes = rawShare.ToBytes();
         var t = _y * r;
         var v = Utils.XorWithHash(t, shareBytes);
         var w = Utils.HashToG2(u, v) * r;
         return new EncryptedShare(u, v, w, rawShare.Id);
     }));
 }
コード例 #5
0
ファイル: DefaultCrypto.cs プロジェクト: LAToken/lachain
 public byte[] RecoverSignatureHashed(byte[] messageHash, byte[] signature, bool useNewChainId)
 {
     if (messageHash.Length != 32)
     {
         throw new ArgumentException(nameof(messageHash));
     }
     if (signature.Length != SignatureSize(useNewChainId))
     {
         throw new ArgumentException(nameof(signature));
     }
     return(EcRecover.Benchmark(() =>
     {
         var parsedSig = new byte[65];
         var pk = new byte[64];
         var encodedRecId = RestoreEncodedRecIdFromSignatureBuffer(signature);
         var recId = (encodedRecId - 36) / 2 / TransactionUtils.ChainId(useNewChainId);
         if (recId < 0 || recId > 3)
         {
             throw new Exception($"Invalid recId={recId}: : recId >= 0 && recId <= 3 ");
         }
         if (!Secp256K1.RecoverableSignatureParseCompact(parsedSig, signature.Take(64).ToArray(), recId))
         {
             throw new ArgumentException(nameof(signature));
         }
         if (!Secp256K1.Recover(pk, parsedSig, messageHash))
         {
             throw new ArgumentException("Bad signature");
         }
         var result = new byte[33];
         if (!Secp256K1.PublicKeySerialize(result, pk, Flags.SECP256K1_EC_COMPRESSED))
         {
             throw new Exception("Cannot serialize recovered public key: how did it happen?");
         }
         return result;
     }));
 }
コード例 #6
0
ファイル: PublicKey.cs プロジェクト: LAToken/lachain
        public RawShare FullDecrypt(EncryptedShare share, List <PartiallyDecryptedShare> us)
        {
            return(FullDecryptBenchmark.Benchmark(() =>
            {
                if (us.Count < _t)
                {
                    throw new Exception("Insufficient number of shares!");
                }

                var ids = new HashSet <int>();
                foreach (var part in us)
                {
                    if (ids.Contains(part.DecryptorId))
                    {
                        throw new Exception($"Id {part.DecryptorId} was provided more than once!");
                    }
                    if (part.ShareId != share.Id)
                    {
                        throw new Exception($"Share id mismatch for decryptor {part.DecryptorId}");
                    }
                    ids.Add(part.DecryptorId);
                }

                var ys = new List <G1>();
                var xs = new List <Fr>();

                foreach (var part in us)
                {
                    xs.Add(Fr.FromInt(part.DecryptorId + 1));
                    ys.Add(part.Ui);
                }

                var u = MclBls12381.LagrangeInterpolate(xs.ToArray(), ys.ToArray());
                return new RawShare(Utils.XorWithHash(u, share.V), share.Id);
            }));
        }
コード例 #7
0
 private bool IsShareValid(PublicKey pubKey, Signature sigShare)
 {
     return(VerifyBenchmark.Benchmark(() => pubKey.ValidateSignature(sigShare, _dataToSign)));
 }
コード例 #8
0
 public Signature Sign()
 {
     return(SignBenchmark.Benchmark(() => _privateKeyShare.HashAndSign(_dataToSign)));
 }