Exemplo n.º 1
0
        public static void KeyExchange(ArraySegment <byte> sharedKey, ArraySegment <byte> publicKey,
                                       ArraySegment <byte> privateKey)
        {
            if (sharedKey.Array == null)
            {
                throw new ArgumentNullException(nameof(sharedKey));
            }

            if (publicKey.Array == null)
            {
                throw new ArgumentNullException(nameof(sharedKey));
            }

            if (privateKey.Array == null)
            {
                throw new ArgumentNullException("privateKey");
            }

            if (sharedKey.Count != 32)
            {
                throw new ArgumentException("sharedKey.Count != 32");
            }

            if (publicKey.Count != 32)
            {
                throw new ArgumentException("publicKey.Count != 32");
            }

            if (privateKey.Count != 64)
            {
                throw new ArgumentException("privateKey.Count != 64");
            }

            FieldOperations.fe_frombytes(out FieldElement edwardsY, publicKey.Array, publicKey.Offset);
            FieldOperations.fe_1(out FieldElement edwardsZ);
            MontgomeryCurve25519.EdwardsToMontgomeryX(out FieldElement montgomeryX, ref edwardsY, ref edwardsZ);
            byte[] h = Sha512.Hash(privateKey.Array, privateKey.Offset, 32);
            ScalarOperations.ScClamp(h, 0);
            MontgomeryOperations.ScalarMult(out FieldElement sharedMontgomeryX, h, 0, ref montgomeryX);
            CryptoBytes.Wipe(h);
            FieldOperations.fe_tobytes(sharedKey.Array, sharedKey.Offset, ref sharedMontgomeryX);
            MontgomeryCurve25519.KeyExchangeOutputHashNaCl(sharedKey.Array, sharedKey.Offset);
        }
Exemplo n.º 2
0
        public void Finish(ArraySegment <byte> output)
        {
            if (output.Array == null)
            {
                throw new ArgumentNullException(nameof(output));
            }

            if (output.Count != 64)
            {
                throw new ArgumentException("output.Count must be 64");
            }

            Update(Padding, 0, Padding.Length);
            ByteIntegerConverter.Array16LoadBigEndian64(out Array16 <ulong> block, _buffer, 0);
            CryptoBytes.InternalWipe(_buffer, 0, _buffer.Length);
            int bytesInBuffer = (int)_totalBytes & (BlockSize - 1);

            if (bytesInBuffer > BlockSize - 16)
            {
                Sha512Internal.Core(out _state, ref _state, ref block);
                block = default(Array16 <ulong>);
            }

            block.x15 = (_totalBytes - 1) * 8;
            Sha512Internal.Core(out _state, ref _state, ref block);

            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 0, _state.x0);
            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 8, _state.x1);
            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 16, _state.x2);
            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 24, _state.x3);
            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 32, _state.x4);
            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 40, _state.x5);
            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 48, _state.x6);
            ByteIntegerConverter.StoreBigEndian64(output.Array, output.Offset + 56, _state.x7);
            _state = default(Array8 <ulong>);
        }
Exemplo n.º 3
0
        public void Update(byte[] data, int offset, int count)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(offset));
            }

            if (count < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(count));
            }

            if (data.Length - offset < count)
            {
                throw new ArgumentException("Requires offset + count <= data.Length");
            }

            Array16 <ulong> block;
            int             bytesInBuffer = (int)_totalBytes & (BlockSize - 1);

            _totalBytes += (uint)count;

            if (_totalBytes >= ulong.MaxValue / 8)
            {
                throw new InvalidOperationException("Too much data");
            }

            // Fill existing buffer
            if (bytesInBuffer != 0)
            {
                int toCopy = Math.Min(BlockSize - bytesInBuffer, count);
                Buffer.BlockCopy(data, offset, _buffer, bytesInBuffer, toCopy);
                offset        += toCopy;
                count         -= toCopy;
                bytesInBuffer += toCopy;

                if (bytesInBuffer == BlockSize)
                {
                    ByteIntegerConverter.Array16LoadBigEndian64(out block, _buffer, 0);
                    Sha512Internal.Core(out _state, ref _state, ref block);
                    CryptoBytes.InternalWipe(_buffer, 0, _buffer.Length);
                    bytesInBuffer = 0;
                }
            }

            // Hash complete blocks without copying
            while (count >= BlockSize)
            {
                ByteIntegerConverter.Array16LoadBigEndian64(out block, data, offset);
                Sha512Internal.Core(out _state, ref _state, ref block);
                offset += BlockSize;
                count  -= BlockSize;
            }

            // Copy remainder into buffer
            if (count > 0)
            {
                Buffer.BlockCopy(data, offset, _buffer, bytesInBuffer, count);
            }
        }
Exemplo n.º 4
0
 public static byte[] ExpandedPrivateKeyFromSeed(byte[] privateKeySeed)
 {
     KeyPairFromSeed(out byte[] publicKey, out byte[] privateKey, privateKeySeed);
     CryptoBytes.Wipe(publicKey);
     return(privateKey);
 }