2018-03-26 09:46:24 +00:00
|
|
|
# Mpint
|
|
|
|
# Copyright 2018 Status Research & Development GmbH
|
|
|
|
# Licensed under either of
|
|
|
|
#
|
|
|
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
|
|
|
|
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
|
|
|
|
#
|
|
|
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
|
|
|
|
|
|
|
import ./private/uint_type, macros
|
|
|
|
export MpUint, MpUintImpl, getMpUintImpl # TODO remove the need to export MpUintImpl and this macro
|
|
|
|
|
|
|
|
type
|
|
|
|
UInt128* = MpUint[128]
|
|
|
|
UInt256* = MpUint[256]
|
|
|
|
|
2018-03-26 10:45:10 +00:00
|
|
|
template make_conv(conv_name: untyped, size: int): untyped =
|
2018-04-21 10:12:05 +00:00
|
|
|
func `convname`*(n: SomeInteger): MpUint[size] {.inline, noInit.}=
|
2018-03-26 10:45:10 +00:00
|
|
|
n.initMpUint(size)
|
|
|
|
|
|
|
|
make_conv(u128, 128)
|
|
|
|
make_conv(u256, 256)
|
|
|
|
|
2018-03-26 09:46:24 +00:00
|
|
|
template make_unary(op, ResultTy): untyped =
|
2018-04-21 10:12:05 +00:00
|
|
|
func `op`*(x: MpUint): ResultTy {.noInit, inline.} =
|
2018-04-24 14:52:13 +00:00
|
|
|
when ResultTy is MpUint:
|
2018-03-26 09:46:24 +00:00
|
|
|
result.data = op(x.data)
|
|
|
|
else:
|
|
|
|
op(x.data)
|
|
|
|
export op
|
|
|
|
|
|
|
|
template make_binary(op, ResultTy): untyped =
|
2018-04-21 10:12:05 +00:00
|
|
|
func `op`*(x, y: MpUint): ResultTy {.noInit, inline.} =
|
2018-03-26 09:46:24 +00:00
|
|
|
when ResultTy is MpUint:
|
|
|
|
result.data = op(x.data, y.data)
|
|
|
|
else:
|
|
|
|
op(x.data, y.data)
|
|
|
|
export `op`
|
|
|
|
|
|
|
|
template make_binary_inplace(op): untyped =
|
2018-04-21 10:12:05 +00:00
|
|
|
func `op`*(x: var MpUint, y: MpUint) {.inline.} =
|
2018-03-26 09:46:24 +00:00
|
|
|
op(x.data, y.data)
|
|
|
|
export op
|
|
|
|
|
2018-04-21 10:12:05 +00:00
|
|
|
import ./private/uint_addsub
|
2018-03-26 09:46:24 +00:00
|
|
|
|
|
|
|
make_binary(`+`, MpUint)
|
|
|
|
make_binary_inplace(`+=`)
|
|
|
|
make_binary(`-`, MpUint)
|
|
|
|
make_binary_inplace(`-=`)
|
2018-04-21 10:12:05 +00:00
|
|
|
|
|
|
|
import ./private/uint_mul
|
2018-03-26 09:46:24 +00:00
|
|
|
make_binary(`*`, MpUint)
|
2018-04-20 09:13:47 +00:00
|
|
|
|
2018-04-21 10:12:05 +00:00
|
|
|
import ./private/uint_div
|
2018-04-20 09:13:47 +00:00
|
|
|
|
2018-03-26 09:46:24 +00:00
|
|
|
make_binary(`div`, MpUint)
|
|
|
|
make_binary(`mod`, MpUint)
|
2018-04-21 10:12:05 +00:00
|
|
|
func divmod*(x, y: MpUint): tuple[quot, rem: MpUint] {.noInit, inline.} =
|
2018-03-26 09:46:24 +00:00
|
|
|
(result.quot.data, result.rem.data) = divmod(x.data, y.data)
|
|
|
|
|
|
|
|
import ./private/uint_comparison
|
|
|
|
|
|
|
|
make_binary(`<`, bool)
|
|
|
|
make_binary(`<=`, bool)
|
2018-04-21 10:12:05 +00:00
|
|
|
make_binary(`==`, bool)
|
|
|
|
func isZero*(x: MpUint): bool {.inline.} = isZero x.data
|
2018-03-26 09:46:24 +00:00
|
|
|
|
|
|
|
import ./private/uint_bitwise_ops
|
|
|
|
|
|
|
|
make_unary(`not`, MpUint)
|
|
|
|
make_binary(`or`, MpUint)
|
|
|
|
make_binary(`and`, MpUint)
|
|
|
|
make_binary(`xor`, MpUint)
|
|
|
|
proc `shr`*(x: Mpuint, y: SomeInteger): MpUint {.noInit, inline, noSideEffect.} =
|
|
|
|
result.data = x.data shr y
|
|
|
|
proc `shl`*(x: Mpuint, y: SomeInteger): MpUint {.noInit, inline, noSideEffect.} =
|
|
|
|
result.data = x.data shl y
|