Esempio n. 1
0
        public static Signature ReadSignature(this BinaryReader reader)
        {
            var kind = (SignatureKind)reader.ReadByte();

            switch (kind)
            {
            case SignatureKind.None:
                return(null);

            case SignatureKind.Ed25519:
            {
                var signature = new Ed25519Signature();
                signature.UnserializeData(reader);
                return(signature);
            }

            case SignatureKind.Ring:
            {
                var signature = new RingSignature();
                signature.UnserializeData(reader);
                return(signature);
            }

            default:
                throw new NotImplementedException("read signature: " + kind);
            }
        }
Esempio n. 2
0
        public RingSignature[] Sign(byte[] msg, byte[] keyImage, IKey[] publicKeys, byte[] secretKey, int index)
        {
            RingSignature[] signatures = new RingSignature[publicKeys.Length];

            byte[][] pubs = publicKeys.Select(pk => pk.Value.ToArray()).ToArray();

            GroupOperations.ge_frombytes(out GroupElementP3 keyImageP3, keyImage, 0);
            GroupElementCached[] image_pre = new GroupElementCached[8];
            GroupOperations.ge_dsm_precomp(image_pre, ref keyImageP3);

            byte[] sum = new byte[32], k = null, h = null;

            IHash hasher = HashFactory.Crypto.SHA3.CreateKeccak256();

            hasher.TransformBytes(msg);

            for (int i = 0; i < publicKeys.Length; i++)
            {
                signatures[i] = new RingSignature();

                if (i == index)
                {
                    k = GetRandomSeed(true);
                    GroupOperations.ge_scalarmult_base(out GroupElementP3 tmp3, k, 0);
                    byte[] tmp3bytes = new byte[32];
                    GroupOperations.ge_p3_tobytes(tmp3bytes, 0, ref tmp3);
                    hasher.TransformBytes(tmp3bytes);
                    tmp3 = Hash2Point(pubs[i]);
                    GroupOperations.ge_scalarmult(out GroupElementP2 tmp2, k, ref tmp3);
                    byte[] tmp2bytes = new byte[32];
                    GroupOperations.ge_tobytes(tmp2bytes, 0, ref tmp2);
                    hasher.TransformBytes(tmp2bytes);
                }
                else
                {
                    signatures[i].C = GetRandomSeed(true);
                    signatures[i].R = GetRandomSeed(true);
                    GroupOperations.ge_frombytes(out GroupElementP3 tmp3, pubs[i], 0);
                    GroupOperations.ge_double_scalarmult_vartime(out GroupElementP2 tmp2, signatures[i].C, ref tmp3, signatures[i].R);
                    byte[] tmp2bytes = new byte[32];
                    GroupOperations.ge_tobytes(tmp2bytes, 0, ref tmp2);
                    hasher.TransformBytes(tmp2bytes);
                    tmp3 = Hash2Point(pubs[i]);
                    GroupOperations.ge_double_scalarmult_precomp_vartime(out tmp2, signatures[i].R, tmp3, signatures[i].C, image_pre);
                    tmp2bytes = new byte[32];
                    GroupOperations.ge_tobytes(tmp2bytes, 0, ref tmp2);
                    hasher.TransformBytes(tmp2bytes);
                    ScalarOperations.sc_add(sum, sum, signatures[i].C);
                }
            }

            h = hasher.TransformFinal().GetBytes();
            ScalarOperations.sc_sub(signatures[index].C, h, sum);
            ScalarOperations.sc_reduce32(signatures[index].C);
            ScalarOperations.sc_mulsub(signatures[index].R, signatures[index].C, secretKey, k);
            ScalarOperations.sc_reduce32(signatures[index].R);

            return(signatures);
        }
Esempio n. 3
0
        public void RingSignatures()
        {
            var rand = new Random();

            int participants = 5;
            var messages = new[] { "hello", "phantasma chain", "welcome to the future" }.Select(Encoding.UTF8.GetBytes).ToArray();
            var keys = Enumerable.Range(0, participants).Select(i => RingSignature.GenerateKeyPair(PhantasmaKeys.Generate())).ToArray();

            foreach (var key in keys)
            {
                Assert.IsTrue(BigInteger.ModPow(RingSignature.GroupParameters.Generator, key.PrivateKey, RingSignature.GroupParameters.Prime) == key.PublicKey);
            }

            var publicKeys = keys.Select(k => k.PublicKey).ToArray();

            var signatures = new RingSignature[participants, messages.Length];

            for (int i = 0; i < participants; ++i)
            {
                for (int j = 0; j < messages.Length; ++j)
                {
                    signatures[i, j] = RingSignature.GenerateSignature(messages[j], publicKeys, keys[i].PrivateKey, i);
                    Assert.IsTrue(signatures[i, j].VerifySignature(messages[j], publicKeys));

                    for (int k = 0; k < messages.Length; ++k)
                    {
                        Assert.IsFalse(signatures[i, j].VerifySignature(messages[k], publicKeys) != (k == j));
                    }

                    var orig     = signatures[i, j];
                    var tampered = new RingSignature(orig.Y0, orig.S.FlipBit(rand.Next(orig.S.GetBitLength())), orig.C);
                    Assert.IsFalse(tampered.VerifySignature(messages[j], publicKeys));

                    tampered = new RingSignature(orig.Y0.FlipBit(rand.Next(orig.Y0.GetBitLength())), orig.S, orig.C);
                    Assert.IsFalse(tampered.VerifySignature(messages[j], publicKeys));

                    var s = (BigInteger[])orig.C.Clone();
                    var t = rand.Next(s.Length);
                    s[t]     = s[t].FlipBit(rand.Next(s[t].GetBitLength()));
                    tampered = new RingSignature(orig.Y0, orig.S, s);
                    Assert.IsFalse(tampered.VerifySignature(messages[j], publicKeys));
                }
            }

            for (int i = 0; i < participants; ++i)
            {
                for (int j = 0; j < messages.Length; ++j)
                {
                    for (int k = 0; k < participants; ++k)
                    {
                        for (int l = 0; l < messages.Length; ++l)
                        {
                            Assert.IsTrue(signatures[i, j].IsLinked(signatures[k, l]) == (i == k));
                        }
                    }
                }
            }
        }
 private void btnGenRingSig_Click(object sender, RoutedEventArgs e)
 {
     using (RingSigKeys[0].Decrypt())
     {
         IEnumerable <Pure.Cryptography.ECC.ECPoint> pubKeys = RingSigKeys.Select(p => p.PublicKey);
         RingSignature sign = message.RingSign(pubKeys.ToList(), RingSigKeys[0].PrivateKey, keyImage.ToByteArray().Reverse().ToArray(), 0);
         sign.RingVerify(message, pubKeys.ToList());
     }
 }
Esempio n. 5
0
        protected override PacketBase ParseBlockBase(ushort version, Memory <byte> spanBody, out Memory <byte> spanPostBody)
        {
            int readBytes = 0;

            byte[] destinationKey = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
            readBytes += Globals.NODE_PUBLIC_KEY_SIZE;

            byte[] destinationKey2 = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
            readBytes += Globals.NODE_PUBLIC_KEY_SIZE;

            byte[] transactionPublicKey = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
            readBytes += Globals.NODE_PUBLIC_KEY_SIZE;

            spanPostBody = ParseUtxoConfidential(version, spanBody.Slice(readBytes), out UtxoConfidentialBase utxoConfidentialBase);

            ushort        readBytesPostBody = 0;
            Memory <byte> keyImage          = spanPostBody.Slice(readBytesPostBody, Globals.NODE_PUBLIC_KEY_SIZE);

            readBytesPostBody += Globals.NODE_PUBLIC_KEY_SIZE;

            ushort ringSignaturesCount = BinaryPrimitives.ReadUInt16LittleEndian(spanPostBody.Span.Slice(readBytesPostBody));

            readBytesPostBody += sizeof(ushort);

            utxoConfidentialBase.KeyImage             = _entityIdentityKeyProvider.GetKey(keyImage);
            utxoConfidentialBase.DestinationKey       = destinationKey;
            utxoConfidentialBase.DestinationKey2      = destinationKey2;
            utxoConfidentialBase.TransactionPublicKey = transactionPublicKey;
            utxoConfidentialBase.PublicKeys           = new IKey[ringSignaturesCount];
            utxoConfidentialBase.Signatures           = new RingSignature[ringSignaturesCount];

            for (int i = 0; i < ringSignaturesCount; i++)
            {
                byte[] publicKey = spanPostBody.Slice(readBytesPostBody, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                IKey   key       = _entityIdentityKeyProvider.GetKey(spanPostBody.Slice(readBytesPostBody, Globals.NODE_PUBLIC_KEY_SIZE));
                utxoConfidentialBase.PublicKeys[i] = key;
                readBytesPostBody += Globals.NODE_PUBLIC_KEY_SIZE;
            }

            for (int i = 0; i < ringSignaturesCount; i++)
            {
                byte[] c = spanPostBody.Slice(readBytesPostBody, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                readBytesPostBody += Globals.NODE_PUBLIC_KEY_SIZE;

                byte[] r = spanPostBody.Slice(readBytesPostBody, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                readBytesPostBody += Globals.NODE_PUBLIC_KEY_SIZE;

                RingSignature ringSignature = new RingSignature {
                    C = c, R = r
                };
                utxoConfidentialBase.Signatures[i] = ringSignature;
            }

            spanPostBody = spanPostBody.Slice(readBytesPostBody);

            return(utxoConfidentialBase);
        }
Esempio n. 6
0
        public static bool RingVerify(this RingSignature signature, byte[] message, List <Cryptography.ECC.ECPoint> pubKeys)
        {
            #region Calculate L{i} & R{i}
            List <byte[]> L = new List <byte[]>();
            List <byte[]> R = new List <byte[]>();

            for (int i = 0; i < RingSignature.RING_SIZE; i++)
            {
                byte[] L_i = (Cryptography.ECC.ECCurve.Secp256r1.G * signature.R[i] + pubKeys[i] * signature.C[i]).ToString().HexToBytes();
                L.Add(L_i);

                BigInteger R_i = ((new BigInteger(signature.R[i].Reverse().Concat(new byte[1]).ToArray()) * new BigInteger(Crypto.Default.Hash256(pubKeys[i].ToString().HexToBytes()).Reverse().Concat(new byte[1]).ToArray())) + (new BigInteger(signature.C[i].Reverse().Concat(new byte[1]).ToArray()) * new BigInteger(signature.KeyImage.Reverse().Concat(new byte[1]).ToArray())).Mod(Cryptography.ECC.ECCurve.Secp256r1.N)).Mod(Cryptography.ECC.ECCurve.Secp256r1.N);
                R.Add(R_i.ToByteArray().Reverse().ToArray());
            }
            #endregion

            #region Calculate Sigma C{i}
            BigInteger SigmaC = BigInteger.Zero;
            for (int i = 0; i < RingSignature.RING_SIZE; i++)
            {
                SigmaC += new BigInteger(signature.C[i].Reverse().Concat(new byte[1]).ToArray());
            }

            SigmaC = SigmaC.Mod(Cryptography.ECC.ECCurve.Secp256r1.N);
            #endregion

            #region Calcuate Hash
            int    totalSize = message.Length + L.Select(p => p.Length).Sum() + R.Select(p => p.Length).Sum();
            byte[] data      = new byte[totalSize];
            int    dstOff    = 0;
            Buffer.BlockCopy(message, 0, data, dstOff, message.Length);
            dstOff += message.Length;

            for (int i = 0; i < RingSignature.RING_SIZE; i++)
            {
                Buffer.BlockCopy(L[i], 0, data, dstOff, L[i].Length);
                dstOff += L[i].Length;
            }

            for (int i = 0; i < RingSignature.RING_SIZE; i++)
            {
                Buffer.BlockCopy(R[i], 0, data, dstOff, R[i].Length);
                dstOff += R[i].Length;
            }

            byte[]     c  = Crypto.Default.Hash256(data);
            BigInteger iC = (new BigInteger(c.Reverse().Concat(new byte[1]).ToArray())).Mod(Cryptography.ECC.ECCurve.Secp256r1.N);

            #endregion

            if (SigmaC != iC)
            {
                return(false);
            }
            return(true);
        }
Esempio n. 7
0
        public void TakePrivate(Address to, string symbol, uint queueID, RingSignature signature)
        {
            Runtime.Expect(Runtime.Nexus.TokenExists(symbol), "invalid token");
            var tokenInfo = this.Runtime.Nexus.GetTokenInfo(symbol);

            Runtime.Expect(tokenInfo.Flags.HasFlag(TokenFlags.Fungible), "token must be fungible");

            var queue = FindQueue(symbol, queueID);

            Runtime.Expect(queue.ID > 0, "invalid queue");

            Runtime.Expect(queue.ID == queueID, "mismatching queue");
            Runtime.Expect(queue.addresses.Count() == queue.size, "queue not full yet");

            var addresses = queue.addresses.All <Address>();

            foreach (var address in addresses)
            {
                Runtime.Expect(address != to, "cant send to anyone already in the queue");
            }

            var msg = this.Runtime.Transaction.ToByteArray(false);

            Runtime.Expect(signature.Verify(msg, addresses), "ring signature failed");

            var signatures = queue.signatures.All <Signature>();

            foreach (RingSignature otherSignature in signatures)
            {
                Runtime.Expect(!signature.IsLinked(otherSignature), "ring signature already linked");
            }

            queue.signatures.Add(signature);

            // TODO this is wrong
            var balances = new BalanceSheet(symbol);

            balances.Add(this.Storage, to, TransferAmount);
        }