在我最近的做的一个同态里,常规的要排序需要将两数(鉴于核心技术看不到明文)相减,并且比较结果是否小于零来判断是否移位。而我所用的方案里第一步就要把数转换成无符号大整数ZZ_q类型,所以结果是不会输出负数的。那如何来判断两个数值未知的无符号数的大小呢。于是我写下本文来记录我所构造的几个方案。
核心思想——利用数值溢出来比较大小
虽然结果不会输出负数,但是无符号数会存在溢出的情况,比如一个无符号数的范围是在【0,216】那么-1转换成无符号数后就会变成2^16 - 1这么大的数。于是,就可以利用这个数之大来判断两数的大小。
- 方案一
设有两数 a b (前提是a,b均小于且不等于2^16的一半大小)
如果有 a - b > a + b 则 a < b
例如 a = 3, b = 5
a - b = -2
a + b = 8
而在无符号数中 -2 是 2^16 - 2 这么大的数字,所以有 a - b > a + b
如果 a = 5, b = 3时呢,那更不用说了,a - b 的结果只会是一个比 a+b 小的一个小整数。
这种方案虽然可行,但是还是效率太低了,因为比较两个数需要分别进行一次同态加减再解密比较大小。于是有了方案一的pro版。
- 方案二
我既然都限制了a,b都小于最大值的一半了,就可以把剩下一半都当作负数的范围。
这样做有啥好处呢?好处就是我可以只算 a - b,而不用算 a + b 了,a - b > 2^15 就相当于 a - b < 0 了。即 a < b。
无论方案一和方案二都把原来的无符号数范围缩小到一半了,这不影响计算吗?
确实影响。但是我的范围是可调的,如过我根据原来的范围就先扩大一倍,那计算时再缩小一倍就相当于没有影响了。当然因为我的范围它跟计算效率是没有关系的,我可以把最大值调的尽可能大,在条件允许的情况下越大越好。
前两种方案解决了比大小问题,但是最后都需要用私钥来解密后才能比大小,可以解决两者的比大小问题。