Skip to content

Overflow when encoding numpy.int64 variables #116

Open
@AuthoStats

Description

@AuthoStats

When working with Numpy arrays, I ran into issues of Overflow errors for simple values. After testing, I found that the issue stemmed from the numpy.int64() datatype. Accessing elements in a numpy array in certain ways yields either a Python int datatype or numpy.int64 datatype. The latter value will cause Overflow errors during the Encoding step regardless of the value used.

The source of this is the change from:
int_rep = int(round(scalar * pow(BASE, -exponent)))
to
int_rep = round(fractions.Fraction(scalar)* fractions.Fraction(BASE) ** -exponent)

Although the latter produces the same numerical value, the data type remains a numpy.int64 data type, whereas the old code would convert it to a python integer, which avoids the eventual Overflow during int_rep % public_key.n

To reproduce:

import sys, math, fractions
import numpy as np
from phe import *
BASE = 16
LOG2_BASE = math.log(BASE, 2)
public_key, private_key = generate_paillier_keypair()
scalar = np.int64(0)
FLOAT_MANTISSA_BITS = sys.float_info.mant_dig
precision= 2**-12
prec_exponent = math.floor(math.log(precision, BASE))
exponent = prec_exponent
print(f"Exponent is {exponent} with type {type(exponent)}")
int_rep = round(fractions.Fraction(scalar)* fractions.Fraction(BASE) ** -exponent)
print(f"Integer Representation is {int_rep} with type {type(int_rep)}")
if abs(int_rep) > public_key.max_int:
    raise ValueError('Integer needs to be within +/- %d but got %d'
                        % (public_key.max_int, int_rep))
print(f"Boolean is {abs(int_rep) > public_key.max_int} with type {type(abs(int_rep) > public_key.max_int)}")
print(f"Message Space is {public_key.n} with type {type(public_key.n)}")
print(f"Max int is {public_key.max_int} with type {type(public_key.max_int)}")
print(f"Pre-mod integer is {int_rep} with type {type(int_rep)}")
print(f"Int representation is {int_rep % public_key.n} with type {type(int_rep % public_key.n)}")

Results in the output:

Exponent is -3 with type <class 'int'>
Integer Representation is 0 with type <class 'numpy.int64'>
Boolean is False with type <class 'numpy.bool'>
Message Space is 4093299914960611076154454533787578959581289998492125181114018178394152381143259675082188008209902629589277524113649765838989914674553123919650964754355090186061631401912263318624324659591997557708788672559568824602328027976345926757402999498477431785905261332426933383936527584684316875370279339658246077469650376555206669856341137276375169669166016379742473704839743919194618007230416266659944199011129118409143247399262217719388418100575681908486778404197758682239390515139663887743361308583944099922333000196944755144800444830909706571603073189184902547818334812327157739004621975723494689058176223158608699653041708414807064308834400223968525343654300847843980229932031740833833638237420339655168209879554389770295321696887140992207523682688296751642050754397764494146304963381200475898981702838357704214479336874785549974224778267706339243552119495008674855538122633053209545487395389320411741764062626452834900290053827 with type <class 'int'>
Max int is 1364433304986870358718151511262526319860429999497375060371339392798050793714419891694062669403300876529759174704549921946329971558184374639883654918118363395353877133970754439541441553197332519236262890853189608200776009325448642252467666499492477261968420444142311127978842528228105625123426446552748692489883458851735556618780379092125056556388672126580824568279914639731539335743472088886648066337043039469714415799754072573129472700191893969495592801399252894079796838379887962581120436194648033307444333398981585048266814943636568857201024396394967515939444937442385913001540658574498229686058741052869566551013902804935688102944800074656175114551433615947993409977343913611277879412473446551722736626518129923431773898962380330735841227562765583880683584799254831382101654460400158632993900946119234738159778958261849991408259422568779747850706498336224951846040877684403181829131796440137247254687542150944966763351274 with type <class 'int'>
Pre-mod integer is 0 with type <class 'numpy.int64'>


OverflowError Traceback (most recent call last)
Cell In[4], line 22
20 print(f"Max int is {public_key.max_int} with type {type(public_key.max_int)}")
21 print(f"Pre-mod integer is {int_rep} with type {type(int_rep)}")
---> 22 print(f"Int representation is {int_rep % public_key.n} with type {type(int_rep % public_key.n)}")

OverflowError: int too big to convert

Whereas:

import sys, math, fractions
import numpy as np
from phe import *
BASE = 16
LOG2_BASE = math.log(BASE, 2)
public_key, private_key = generate_paillier_keypair()
scalar = np.int64(0)
FLOAT_MANTISSA_BITS = sys.float_info.mant_dig
precision= 2**-12
prec_exponent = math.floor(math.log(precision, BASE))
exponent = prec_exponent
print(f"Exponent is {exponent} with type {type(exponent)}")
int_rep = int(round(scalar * pow(BASE, -exponent)))
print(f"Integer Representation is {int_rep} with type {type(int_rep)}")
if abs(int_rep) > public_key.max_int:
    raise ValueError('Integer needs to be within +/- %d but got %d'
                        % (public_key.max_int, int_rep))
print(f"Boolean is {abs(int_rep) > public_key.max_int} with type {type(abs(int_rep) > public_key.max_int)}")
print(f"Message Space is {public_key.n} with type {type(public_key.n)}")
print(f"Max int is {public_key.max_int} with type {type(public_key.max_int)}")
print(f"Pre-mod integer is {int_rep} with type {type(int_rep)}")
print(f"Int representation is {int_rep % public_key.n} with type {type(int_rep % public_key.n)}")

Results in the output:

Exponent is -3 with type <class 'int'>
Integer Representation is 0 with type <class 'int'>
Boolean is False with type <class 'bool'>
Message Space is 4632064407707281026303273495076274986239900031399402470241477394127551953831094191281219038334713985254889185304161653243503759185417918664119368195923259715525156625229037559004097318182716964686573978619780826614950377163034890125922697125576054790349892640400958036205926844105110567864591794189955654364071048561624817664074029218202602537898448018943343553782659064533206705898849506642470405071106707182419590486867363012636624439424863228881364444909045598227897365624132947926421182200790667982680508194894394565171205106951397193487804433878510272933308362102718591289553326209129351152085387466861256468847086147860954708068049795811665522470072358481269243089031014011336328919524507588640699013554558359868959494256742349725955028495834741794640003777873741370503372256258008908507825331012875642390732706557626968755786169246025239136979616812358792860642118776326122686655274154596895264317344200617176130890163 with type <class 'int'>
Max int is 1544021469235760342101091165025424995413300010466467490080492464709183984610364730427073012778237995084963061768053884414501253061805972888039789398641086571841718875076345853001365772727572321562191326206593608871650125721011630041974232375192018263449964213466986012068642281368370189288197264729985218121357016187208272554691343072734200845966149339647781184594219688177735568632949835547490135023702235727473196828955787670878874813141621076293788148303015199409299121874710982642140394066930222660893502731631464855057068368983799064495934811292836757644436120700906197096517775403043117050695129155620418822949028715953651569356016598603888507490024119493756414363010338003778776306508169196213566337851519453289653164752247449908651676165278247264880001259291247123501124085419336302835941777004291880796910902185875656251928723082008413045659872270786264286880706258775374228885091384865631754772448066872392043630053 with type <class 'int'>
Pre-mod integer is 0 with type <class 'int'>
Int representation is 0 with type <class 'int'>

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions