Skip to content

Commit

Permalink
Verkle IPA: Backend maintenance and further testing (#364)
Browse files Browse the repository at this point in the history
* added tests, some fixes

* rm bin

* added tests, some fixes

* rm bin

* changes

* add: added recursive divide and conquer with (mostly) Views

* rm: prev loop code

* fix: checkIPAProof order

* small fix

* rm binary, cleanup leftovers

* ipa fixes with divide and conquer

* fix: upstreamed transcript fixed indent

* rm: generateChallengeScalar from Upstream

* rm: transcript from Upstream

* transcript upstream

* rm bin

* add: types recognizable from nim-eth-verkle
  • Loading branch information
agnxsh authored Mar 9, 2024
1 parent c7979b0 commit 976c8bb
Show file tree
Hide file tree
Showing 12 changed files with 673 additions and 412 deletions.
29 changes: 15 additions & 14 deletions constantine/eth_verkle_ipa/barycentric_form.nim
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ func computeBarycentricCoefficients*(res_inv: var openArray[Fr[Banderwagon]], pr

func getInvertedElement*(res: var Fr[Banderwagon], precomp : PrecomputedWeights, element : int, is_negative: bool) =
var index: int
index = element - 1
index = element - 1

if is_negative:
var midpoint = precomp.invertedDomain.len div 2
Expand All @@ -136,30 +136,30 @@ func getBarycentricInverseWeight*(res: var Fr[Banderwagon], precomp: Precomputed


func absIntChecker*[int] (res: var int, x : int) =
var is_negative {.noInit.}: bool
var is_negative = false
if x < 0:
is_negative = true

if is_negative == true:
res = - x
if is_negative == true:
res = -x
else:
res = x
res = x


func divisionOnDomain*(res: var array[VerkleDomain,Fr[Banderwagon]], precomp: PrecomputedWeights, index: var int, f: openArray[Fr[Banderwagon]]) =
func divisionOnDomain*(res: var array[VerkleDomain,Fr[Banderwagon]], precomp: PrecomputedWeights, index: var uint8, f: openArray[Fr[Banderwagon]]) =
## Computes f(x) - f(x_i) / x - x_i using the barycentric weights, where x_i is an element in the
var is_negative = true
let index = int(index)
var y = f[index]

for i in 0 ..< VerkleDomain:
if i != index:
var denominator = i - index
if i != int(index):

var denominator = i - int(index)
var absDenominator {.noInit.}: int
absDenominator.absIntChecker(denominator)

if absDenominator > 0:
is_negative = false

doAssert absDenominator > 0, "Absolute Denominator should be greater than 0!"
is_negative = false

var denominatorInv {.noInit.}: Fr[Banderwagon]
denominatorInv.getInvertedElement(precomp, absDenominator, is_negative)
Expand All @@ -170,9 +170,10 @@ func divisionOnDomain*(res: var array[VerkleDomain,Fr[Banderwagon]], precomp: Pr
var weight_ratios {.noInit.}: Fr[Banderwagon]
var dummy {.noInit.} : int
dummy = i
weight_ratios.getWeightRatios(precomp, index, dummy)
var dummy2 = int(index)
weight_ratios.getWeightRatios(precomp, dummy2, dummy)

var tmp {.noInit.}: Fr[Banderwagon]
tmp.prod(weight_ratios, res[i])
res[int(index)] -= tmp

res[index] -= tmp
72 changes: 55 additions & 17 deletions constantine/eth_verkle_ipa/common_utils.nim
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@
## IPAConfiguration contains all of the necessary information to create Pedersen + IPA proofs
## such as the SRS
import
./[eth_verkle_constants],
./[eth_verkle_constants, barycentric_form],
../platforms/primitives,
../math/config/[type_ff, curves],
../math/elliptic/ec_twistededwards_projective,
../hashes,
../math/arithmetic,
../math/elliptic/ec_scalar_mul,
../math/elliptic/[ec_multi_scalar_mul, ec_multi_scalar_mul_scheduler],
../platforms/[bithacks,views],
../platforms/[bithacks],
../../research/kzg/strided_views,
../curves_primitives,
../math/io/[io_bigints, io_fields],
../serialization/[codecs_banderwagon,codecs_status_codes, endians]
Expand All @@ -29,13 +30,13 @@ import
# ############################################################


func generate_random_points* [EC_P](points: var openArray[EC_P], ipaTranscript: var IpaTranscript, num_points: uint64) =
func generate_random_points* [EC_P](points: var openArray[EC_P], num_points: uint64) =
## generate_random_points generates random points on the curve with the hardcoded VerkleSeed
var points_found : seq[EC_P]
var incrementer : uint64 = 0
var idx: int = 0
while true:
var ctx : sha256
var ctx {.noInit.}: sha256
ctx.init()
ctx.update(VerkleSeed)
ctx.update(incrementer.toBytes(bigEndian))
Expand Down Expand Up @@ -75,7 +76,7 @@ func computeInnerProducts* [Fr] (res: var Fr, a,b : openArray[Fr])=
for i in 0 ..< b.len:
var tmp : Fr
tmp.prod(a[i], b[i])
res.sum(res,tmp)
res += tmp

func computeInnerProducts* [Fr] (res: var Fr, a,b : View[Fr])=
debug: doAssert (a.len == b.len).bool() == true, "Scalar lengths don't match!"
Expand All @@ -91,33 +92,34 @@ func computeInnerProducts* [Fr] (res: var Fr, a,b : View[Fr])=
#
# ############################################################

func foldScalars* [Fr] (res: var openArray[Fr], a,b : openArray[Fr], x: Fr)=
func foldScalars*(res: var openArray[Fr[Banderwagon]], a,b : View[Fr[Banderwagon]], x: Fr[Banderwagon])=
## Computes res[i] = a[i] + b[i] * x
debug: doAssert a.len == b.len , "Lengths should be equal!"
doAssert a.len == b.len , "Lengths should be equal!"

for i in 0 ..< a.len:
var bx {.noInit.}: Fr
bx.prod(x, b[i])
res[i].sum(bx, a[i])
var bx {.noInit.}: Fr[Banderwagon]
bx.prod(b[i], x)
res[i].sum(a[i], bx)

func foldPoints* [EC_P] (res: var openArray[EC_P], a,b : var openArray[EC_P], x: Fr)=
func foldPoints*(res: var openArray[EC_P], a,b : View[EC_P], x: Fr[Banderwagon])=
## Computes res[i] = a[i] + b[i] * x
debug: doAssert a.len == b.len , "Should have equal lengths!"
doAssert a.len == b.len , "Should have equal lengths!"

for i in 0 ..< a.len:
var bx {.noInit.}: EC_P

b[i].scalarMul(x.toBig())
bx = b[i]
res[i].sum(bx, a[i])
var x_big {.noInit.}: matchingOrderBigInt(Banderwagon)
x_big.fromField(x)
bx.scalarMul(x_big)
res[i].sum(a[i],bx)


func computeNumRounds*(res: var uint32, vectorSize: SomeUnsignedInt)=
## This method takes the log2(vectorSize), a separate checker is added to prevent 0 sized vectors
## An additional checker is added because we also do not allow for vectors whose size is a power of 2.
debug: doAssert (vectorSize == uint64(0)).bool() == false, "Zero is not a valid input!"

var isP2 : bool = isPowerOf2_vartime(vectorSize)
let isP2 = isPowerOf2_vartime(vectorSize)

debug: doAssert isP2 == true, "not a power of 2, hence not a valid inputs"

Expand All @@ -143,5 +145,41 @@ func pedersen_commit_varbasis*[EC_P] (res: var EC_P, groupPoints: openArray[EC_P
for i in 0 ..< g:
groupPoints_aff[i].affine(groupPoints[i])

res.multiScalarMul_reference_vartime(poly_big,groupPoints)
res.multiScalarMul_reference_vartime(poly_big, groupPoints_aff)

func evalOutsideDomain* [Fr] (res: var Fr, precomp: PrecomputedWeights, f: openArray[Fr], point: Fr)=
# Evaluating the point z outside of VerkleDomain, here the VerkleDomain is 0-256, whereas the FieldSize is
# everywhere outside of it which is upto a 253 bit number, or 2²⁵³.
var pointMinusDomain: array[VerkleDomain, Fr]
var pointMinusDomain_inv: array[VerkleDomain, Fr]
for i in 0 ..< VerkleDomain:
var i_fr {.noInit.}: Fr
i_fr.fromInt(i)

pointMinusDomain[i].diff(point, i_fr)
pointMinusDomain_inv[i].inv(pointMinusDomain[i])

var summand: Fr
summand.setZero()

for x_i in 0 ..< pointMinusDomain_inv.len:
var weight: Fr
weight.getBarycentricInverseWeight(precomp, x_i)
var term: Fr
term.prod(weight, f[x_i])
term *= pointMinusDomain_inv[x_i]

summand.sum(summand,term)

res.setOne()

for i in 0 ..< VerkleDomain:
var i_fr: Fr
i_fr.fromInt(i)

var tmp: Fr
tmp.diff(point, i_fr)
res *= tmp

res *= summand

8 changes: 6 additions & 2 deletions constantine/eth_verkle_ipa/eth_verkle_constants.nim
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ type
EC_P* = ECP_TwEdwards_Prj[Fp[Banderwagon]]
EC_P_Aff* = ECP_TwEdwards_Aff[Fp[Banderwagon]]

type Bytes* = array[32, byte]

type
Point* = EC_P
Field* = Fr[Banderwagon]

type
IPAProof* = object
L_vector*: array[8,EC_P]
Expand Down Expand Up @@ -57,8 +63,6 @@ type

const VerkleSeed* = asBytes"eth_verkle_oct_2021"

type Bytes* = array[32, byte]

type IpaTranscript* [H: CryptoHash, N: static int] = object
ctx*: H
label*: array[N, byte]
Expand Down
Loading

0 comments on commit 976c8bb

Please sign in to comment.