Пример #1
0
        /// <summary>
        /// <see cref="ABCrypto"/> によって暗号化された価格を復号化します。
        /// </summary>
        /// <param name="crypto">暗号化オブジェクト。</param>
        /// <param name="cipherBytes">暗号化された価格を表す暗号データ。</param>
        /// <param name="price">復号化された価格。</param>
        /// <returns>復号化に成功した場合は <c>true</c>、それ以外なら <c>false</c>。</returns>
        /// <exception cref="ArgumentNullException"><paramref name="crypto"/> is <c>null</c>.</exception>
        public static bool TryDecryptPrice(this ABCrypto crypto, ReadOnlySpan <byte> cipherBytes, out decimal price)
        {
            if (crypto == null)
            {
                throw new ArgumentNullException(nameof(crypto));
            }
            if (cipherBytes.Length != CipherSize)
            {
                goto Failure;
            }

            Span <byte> microPriceData = stackalloc byte[PricePayloadSize];

            if (!crypto.TryDecrypt(cipherBytes, microPriceData, out _))
            {
                goto Failure;
            }

            price = (decimal)BinaryPrimitives.ReadInt64BigEndian(microPriceData) / MicrosPerCurrencyUnit;
            return(true);

Failure:
            price = default;
            return(false);
        }
Пример #2
0
        /// <summary>
        /// 価格を暗号化します。
        /// </summary>
        /// <param name="crypto">暗号化オブジェクト。</param>
        /// <param name="price">暗号化対象の価格。</param>
        /// <returns>暗号化された価格を表す暗号文。常に非 <c>null</c>。</returns>
        /// <exception cref="ArgumentNullException"><paramref name="crypto"/> is <c>null</c>.</exception>
        public static string EncryptPrice(this ABCrypto crypto, decimal price)
        {
            if (crypto == null)
            {
                throw new ArgumentNullException(nameof(crypto));
            }

            Span <byte> iv      = stackalloc byte[ABCrypto.IVSize];
            var         success = ABIV.TryCreate(iv);

            Debug.Assert(success);

            return(EncryptPrice(crypto, price, iv));
        }
Пример #3
0
        /// <summary>
        /// <see cref="ABCrypto"/> によって暗号化された暗号文を価格に復号化します。
        /// </summary>
        /// <param name="crypto">暗号化オブジェクト。</param>
        /// <param name="cipherPrice">暗号化された価格を表す暗号文。</param>
        /// <param name="price">復号化された価格。</param>
        /// <returns>復号化に成功した場合は <c>true</c>、それ以外なら <c>false</c>。</returns>
        /// <exception cref="ArgumentNullException"><paramref name="crypto"/> is <c>null</c>.</exception>
        public static bool TryDecryptPrice(this ABCrypto crypto, string cipherPrice, out decimal price)
        {
            if (crypto == null)
            {
                throw new ArgumentNullException(nameof(crypto));
            }

            if (!ABCipherEncoder.TryDecode(cipherPrice, out var cipherBytes))
            {
                goto Failure;
            }

            return(TryDecryptPrice(crypto, cipherBytes, out price));

Failure:
            price = default;
            return(false);
        }
Пример #4
0
        /// <summary>
        /// 価格を暗号化します。
        /// </summary>
        /// <param name="crypto">暗号化オブジェクト。</param>
        /// <param name="price">暗号化対象の価格。</param>
        /// <param name="inputIV">
        /// 暗号化に使用される初期化ベクトル。
        /// 長さが <see cref="ABCrypto.IVSize"/> に満たない場合は不足分を 0 で埋め、<see cref="ABCrypto.IVSize"/> を超える場合は <see cref="ABCrypto.IVSize"/> まで切り詰めて使用します。
        /// </param>
        /// <returns>暗号化された価格を表す暗号文。常に非 <c>null</c>。</returns>
        /// <exception cref="ArgumentNullException"><paramref name="crypto"/> is <c>null</c>.</exception>
        /// <exception cref="OverflowException">
        /// <paramref name="price"/> が <c><see cref="long.MaxValue"/> / 1_000_000</c> より大きい、
        /// または <c><see cref="long.MinValue"/> / 1_000_000 より小さい。</c>
        /// </exception>
        public static string EncryptPrice(this ABCrypto crypto, decimal price, ReadOnlySpan <byte> inputIV)
        {
            if (crypto == null)
            {
                throw new ArgumentNullException(nameof(crypto));
            }

            var cipherBytes = ArrayPool <byte> .Shared.RentAsSegment(CipherSize);

            try {
                var success = TryEncryptPrice(crypto, price, inputIV, cipherBytes);
                Debug.Assert(success);

                return(ABCipherEncoder.Encode(cipherBytes));
            }
            finally {
                ArrayPool <byte> .Shared.Return(cipherBytes.Array);
            }
        }
Пример #5
0
        /// <summary>
        /// 価格を暗号化します。
        /// </summary>
        /// <param name="crypto">暗号化オブジェクト。</param>
        /// <param name="price">暗号化対象の価格。</param>
        /// <param name="inputIV">
        /// 暗号化に使用される初期化ベクトル。
        /// 長さが <see cref="ABCrypto.IVSize"/> に満たない場合は不足分を 0 で埋め、<see cref="ABCrypto.IVSize"/> を超える場合は <see cref="ABCrypto.IVSize"/> まで切り詰めて使用します。
        /// </param>
        /// <param name="destination">
        /// 暗号データの書き込み先となる <see cref="byte"/> スパン。
        /// 少なくとも <see cref="CipherSize"/> 以上の長さが必要です。
        /// </param>
        /// <returns>
        /// 暗号化に成功した場合は <c>true</c>。
        /// <paramref name="destination"/> の長さが <see cref="CipherSize"/> を満たしていない場合は <c>false</c>。
        /// </returns>
        /// <exception cref="ArgumentNullException"><paramref name="crypto"/> is <c>null</c>.</exception>
        /// <exception cref="OverflowException">
        /// <paramref name="price"/> が <c><see cref="long.MaxValue"/> / 1_000_000</c> より大きい、
        /// または <c><see cref="long.MinValue"/> / 1_000_000 より小さい。</c>
        /// </exception>
        public static bool TryEncryptPrice(this ABCrypto crypto, decimal price, ReadOnlySpan <byte> inputIV, Span <byte> destination)
        {
            if (crypto == null)
            {
                throw new ArgumentNullException(nameof(crypto));
            }
            if (destination.Length < CipherSize)
            {
                return(false);
            }

            Span <byte> microPriceData = stackalloc byte[PricePayloadSize];

            BinaryPrimitives.WriteInt64BigEndian(microPriceData, (long)(price * MicrosPerCurrencyUnit));

            var success = crypto.TryEncrypt(microPriceData, inputIV, destination, out var bytesWritten);

            Debug.Assert(success);
            Debug.Assert(bytesWritten == CipherSize);
            return(true);
        }