Files
EWF/library/crypto/eapml/facilities/integer_x_gcd.e
jvelilla c9343688f3 Added eel and eapml in EWF libraries.
Removed them from gitmodule
2011-10-27 08:29:01 -03:00

146 lines
3.8 KiB
Plaintext

note
description: "Summary description for {INTEGER_X_GCD}."
author: "Colin LeMahieu"
date: "$Date$"
revision: "$Revision$"
quote: "'Need' now means wanting someone else's money. 'Greed' means wanting to keep your own. 'Compassion' is when a politician arranges the transfer. - Joseph Sobran, columnist."
deferred class
INTEGER_X_GCD
inherit
INTEGER_X_FACILITIES
SPECIAL_GCD
rename
gcd as gcd_special
export
{NONE}
all
end
feature
gcd (g: READABLE_INTEGER_X; u: READABLE_INTEGER_X; v: READABLE_INTEGER_X)
local
g_zero_bits: INTEGER
u_zero_bits: INTEGER
v_zero_bits: INTEGER
g_zero_limbs: INTEGER
u_zero_limbs: INTEGER
v_zero_limbs: INTEGER
tp: SPECIAL [NATURAL_32]
tp_offset: INTEGER
up: SPECIAL [NATURAL_32]
up_offset: INTEGER
usize: INTEGER
vp: SPECIAL [NATURAL_32]
vp_offset: INTEGER
vsize: INTEGER
gsize: INTEGER
junk: NATURAL_32
cy_limb: NATURAL_32
carry: CELL [NATURAL_32]
do
create carry.put (0)
up := u.item
usize := u.count.abs
vp := v.item
vsize := v.count.abs
if usize = 0 then
g.count := vsize
if g = v then
else
g.resize (vsize)
g.item.copy_data (vp, 0, 0, vsize)
end
elseif vsize = 0 then
g.count := usize
if g = u then
else
g.resize (usize)
g.item.copy_data (up, up_offset, 0, usize)
end
elseif usize = 1 then
g.count := 1
g.item [0] := gcd_1 (vp, vp_offset, vsize, up [up_offset])
elseif vsize = 1 then
g.count := 1
g.item [0] := gcd_1 (up, up_offset, usize, vp [vp_offset])
else
from
until
up [up_offset] /= 0
loop
up_offset := up_offset + 1
end
u_zero_limbs := up_offset - 0
usize := usize - u_zero_limbs
u_zero_bits := trailing_zeros (up [up_offset])
tp := up
tp_offset := up_offset
create up.make_filled (0, usize)
if u_zero_bits /= 0 then
rshift (up, up_offset, tp, tp_offset, usize, u_zero_bits, carry)
junk := carry.item
usize := usize - (up [up_offset + usize - 1] = 0).to_integer
else
up.copy_data (tp, tp_offset, up_offset, usize)
end
from
until
vp [vp_offset] /= 0
loop
vp_offset := vp_offset + 1
end
v_zero_limbs := vp_offset - 0
vsize := vsize - v_zero_limbs
v_zero_bits := trailing_zeros (vp [vp_offset])
tp := vp
tp_offset := vp_offset
create vp.make_filled (0, vsize)
if v_zero_bits /= 0 then
rshift (vp, vp_offset, tp, tp_offset, vsize, v_zero_bits, carry)
junk := carry.item
vsize := vsize - (vp [vp_offset + vsize - 1] = 0).to_integer
else
vp.copy_data (tp, tp_offset, vp_offset, vsize)
end
if u_zero_limbs > v_zero_limbs then
g_zero_limbs := v_zero_limbs
g_zero_bits := v_zero_bits
elseif u_zero_limbs < v_zero_limbs then
g_zero_limbs := u_zero_limbs
g_zero_bits := u_zero_bits
else
g_zero_limbs := u_zero_limbs
g_zero_bits := u_zero_bits.min (v_zero_bits)
end
if usize < vsize or (usize = vsize and up [up_offset + usize - 1] < vp [vp_offset + vsize - 1]) then
vsize := gcd_special (vp, vp_offset, vp, vp_offset, vsize, up, up_offset, usize)
else
vsize := gcd_special (vp, vp_offset, up, up_offset, usize, vp, vp_offset, vsize)
end
gsize := vsize + g_zero_limbs
if g_zero_bits /= 0 then
gsize := gsize + ((vp [vp_offset + vsize - 1] |>> (32 - g_zero_bits)) /= 0).to_integer
g.resize (gsize)
g.item.fill_with (0, 0, g_zero_limbs)
tp := g.item
tp_offset := g_zero_limbs
lshift (tp, tp_offset, vp, vp_offset, vsize, g_zero_bits, carry)
cy_limb := carry.item
if cy_limb /= 0 then
tp [tp_offset + vsize] := cy_limb
end
else
g.resize (gsize)
g.item.fill_with (0, 0, g_zero_limbs)
g.item.copy_data (vp, vp_offset, g_zero_limbs, vsize)
end
g.count := gsize
end
ensure
g.count /= 0
end
end