The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]metanet.ch.
Note that this vignette follows the exact same structure as BFV, and the variables have the same values.
The functions that wrapped several steps in the BFV vignette, are simply unwrapped here for the reader to see what is going on under the hood.
Load libraries that will be used.
Set some parameters.
Set a working seed for random numbers
Create the secret key:
# generate a secret key
s = polynomial( sample( c(-1,0,1), n, replace=TRUE ) )
print(s)
#> 1 + x + x^2 + x^4 + x^8 - x^9 - x^12 + x^14 - x^15
We randomly draw from the set [-1, 0, 1] with replacement n values. These integers are used as the parameters of the polynomial used as the secret key.
Create and the polynomial a, which will go into the public key:
# generate a
a = polynomial(sample.int(q, n, replace=TRUE))
print(a)
#> 91 + 348*x + 649*x^2 + 355*x^3 + 840*x^4 + 26*x^5 + 519*x^6 + 426*x^7 + 649*x^8
#> + 766*x^9 + 211*x^10 + 590*x^11 + 593*x^12 + 555*x^13 + 871*x^14 + 373*x^15
For the polynomial a, we sample from positive integers up to q, n values, with replacement.
Create and the polynomial e, which will go into the public key:
# generate the error
e = polynomial( coef=round(stats::rnorm(n, 0, n/3)) )
print(e)
#> -4 - x - 2*x^2 - 6*x^3 + 6*x^5 - x^6 - 6*x^7 - 4*x^8 + 4*x^9 - 2*x^10 - 7*x^11
#> - 3*x^12 - x^13 + 5*x^14 - x^15
Some error noise is generated, with values bounded by 1/3 of n.
Generate the public key part 0.
# generate the public key
temp = -(a*s + e)
temp = temp %% pm
pk0 = CoefMod(temp, q)
print(pk0)
#> 560 + 287*x + 70*x^2 + 788*x^3 + 534*x^4 + 150*x^5 + 43*x^6 + 331*x^7 + 328*x^8
#> + 318*x^9 + 184*x^10 + 519*x^11 + 504*x^12 + 783*x^13 + 79*x^14 + 425*x^15
Generate public key part 1.
Part 1 of the public key is simply equal to a.
Create a polynomial message
Create error polynomials for the encryption
# polynomials for encryption
e1 = polynomial( coef=round(stats::rnorm(n, 0, n/3)) )
e2 = polynomial( coef=round(stats::rnorm(n, 0, n/3)) )
Create the term u for encryption.
u = polynomial( sample( c(-1,0,1), (n-1), replace=TRUE) )
print(u)
#> x^3 - x^5 + x^9 + x^11 + x^13 - x^14
Generate the ciphertext part 0.
temp = pk0 * u + e1 + floor(q/p) * m
temp = temp %% pm
ct0 = CoefMod(temp, q)
print(ct0)
#> 157 + 787*x + 337*x^2 + 236*x^3 + 454*x^4 + 575*x^5 + 87*x^6 + 14*x^7 + 448*x^8
#> + 640*x^10 + 747*x^11 + 711*x^12 + 564*x^13 + 866*x^14 + 678*x^15
Generate the ciphertext part 0.
temp = pk1 * u + e2
temp = temp %% pm
ct1 = CoefMod(temp, q)
print(ct1)
#> 760 + 698*x + 679*x^2 + 477*x^3 + 329*x^4 + 414*x^5 + 487*x^6 + 165*x^7 +
#> 111*x^8 + 642*x^9 + 409*x^10 + 565*x^11 + 660*x^12 + 644*x^13 + 469*x^14 +
#> 297*x^15
Decrypt
Round (remove the error) then mod p
These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.