bristolcrypto/SPDZ-2

Strange bug when convert from cint to regint

Closed this issue · 4 comments

Update: I think there's a limit when do cint-regint conversion of a big value

b = cint(20971520)
print_ln('b should be 20971520: %s, regint(b): %s, regint(20971520): %s', b, regint(b), regint(20971520))
# b should be 20971520: 20971520, regint(b): 4194304, regint(20971520): 20971520

both cint and regint could seperately hold such a big value, but the conversion may overflow. I noticed that to_signed_bigint() in Instruction.cpp may cause this, but I don't know how to change the related paramters to see the change.

Why I need to convert such a big number is I want to add abs() to type cfix, and cfix is cint*2^20. I found this because comparison between cfix is broken. Message below are my initial issues.


BELOWS ARE OLD MESSAGE

I want to add abs feature for type cfix, so I checked if less_than of cfix works well.

a = cfix(1)
b = sfix(1.5)
c = cfix(12.34)
d = cfix(20)

test(c > 12, 1) # expected 1, got 1
test(c <= 20, 1) # expected 1, got 0. That's wrong
test(c <= d, 1) # expected 1, got 0. Wrong
test(c < d, 1) # expected 1, got 0. Wrong
print_ln('1049576 as factor, c.v is %s, d.v is %s', c.v, d.v) #1049576 as factor, c.v is 12939428, d.v is 20971520. So I guess cint(12939428) < cint(20971520) doesn't work

I'm not sure about your code, it's quite sophisticated so I'm try to track in a primitive way.

a = cint(12939428)
b = cint(20971520)
test(a < b, 1) # expected 1, got 0. Wrong
a = regint(12939428)
b = regint(20971520)
test(a < b, 1) # expected 1, got 1. That's right. I think this is the correct underlying comparision according to types.py
print_ln('type(a) is %s', type(a)) # type(a) is <class 'Compiler.types.regint'> check if confused of NewClass and ClassicClass of python
a = regint(12939428)
b = cint(20971520)
test(a < b, 1) # expected 1, got 0. Wrong
test(isinstance(b, type(a)), 0) # expected 0, got False. Check the if-condition will run

So I think regint(12939428) < cint(20971520) fails while regint(12939428) < regint(20971520) works. But I've also checked the condition that type cint should be converted into regint. Totally confused

in fact cfix(12.34) < cfix(20) is False

That is because by default SPDZ compiles with a 24bit prime (if it doesn't figure out that it needs a bigger prime). Thus declaring cfix(20) means an sint(20 * 2 ** fixed_precision), see here, which overflows the 24 bit prime.

So the fix is either by compiling your program with -p 128 or add this line at the beginning of your program:
program.set_bit_length(128)

oh now I understand