Skip to content

Commit

Permalink
refactor(ipa): enable IPA Proof consistency test
Browse files Browse the repository at this point in the history
  • Loading branch information
mratsim committed Jun 19, 2024
1 parent c96a7b6 commit 189e2a1
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 63 deletions.
48 changes: 27 additions & 21 deletions constantine/commitments/eth_verkle_ipa.nim
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ type IpaProof*[logN: static int, EC, F] = object
R*{.align: 64.}: array[logN, EC] # arrays of right elements for each of the log₂(N) iterations of ipa_prove
a0*: F # unique a0 coefficient after recursively

func innerProduct[F](r: var F, a, b: View[F]) =
func innerProduct[F](r: var F, a, b: distinct(View[F] or MutableView[F])) =
## Compute the inner product ⟨a, b⟩ = ∑aᵢ.bᵢ
debug: doAssert a.len == b.len
r.setZero()
Expand All @@ -149,8 +149,8 @@ func ipa_prove*[N, logN: static int, EcAff, F](
opening_challenge: F) =

static:
doAssert N.isPowerOf2_vartime()
doAssert logN == N.log2_vartime()
doAssert N.uint.isPowerOf2_vartime()
doAssert logN == N.uint.log2_vartime()

when EcAff is ECP_ShortW_Aff:
type EC = jacobian(EcAff)
Expand All @@ -159,16 +159,20 @@ func ipa_prove*[N, logN: static int, EcAff, F](

# Allocs
# -----------------------------------
let basisPolysOpened = allocHeapAligned(array[N, F])
domain.getLagrangeBasisPolysAt(basisPolysOpened[], opening_challenge)

let gprime = allocHeapArrayAligned(Ec, N div 2)
let aprime = allocHeapAligned(array[N, F], alignment = 64)
let bprime = allocHeapAligned(array[N, F], alignment = 64)
let gprime = allocHeapAligned(array[N, EcAff], alignment = 64)
let gg = allocHeapAligned(array[N div 2, Ec], alignment = 64) # Temp for batchAffine

# Aliases and unowned views for zero-copy splitting
# -------------------------------------------------
var a = poly.evals.toView()
var G = crs.evals.toView()
var b = basisPolysOpened[].toView()
var a = aprime[].toMutableView()
var b = bprime[].toMutableView()
var G = gprime[].toMutableView()

a.copyFrom(poly.evals)
domain.getLagrangeBasisPolysAt(bprime[], opening_challenge)
G.copyFrom(crs.evals)

# Protocol
# -------------------------------------------------
Expand Down Expand Up @@ -208,16 +212,16 @@ func ipa_prove*[N, logN: static int, EcAff, F](
# but that's extra allocations / data movements.
var lrAff {.noInit.}: array[2, EcAff]
var lr {.noInit.}: array[2, Ec]
gL.pedersen_commit(lr[0], aR)
gR.pedersen_commit(lr[1], aL)
gL.asView().pedersen_commit(lr[0], aR.asView())
gR.asView().pedersen_commit(lr[1], aL.asView())
lr[0] ~+= aRbL_Q
lr[1] ~+= aLbR_Q

lrAff.batchAffine(lr)
transcript.absorb("L", lrAff[0])
transcript.absorb("R", lrAff[1])
proof.buf.L[i] = lrAff[0]
proof.buf.R[i] = lrAff[1]
proof.L[i] = lrAff[0]
proof.R[i] = lrAff[1]

var x {.noInit.}, xinv {.noInit.}: F
transcript.squeezeChallenge("x", x)
Expand All @@ -244,22 +248,25 @@ func ipa_prove*[N, logN: static int, EcAff, F](

let xinvbig {.noInit.} = xinv.toBig()
for j in 0 ..< gL.len:
gprime[j].fromAffine(gR[j])
gprime[j].scalarMul_vartime(xinvbig)
gprime ~+= gL[j]
gg[j].fromAffine(gR[j])
gg[j].scalarMul_vartime(xinvbig)
gg[j] ~+= gL[j]

batchAffine(
gL.toOpenArray(),
gprime.toOpenArray(0, gL.len-1)
gL.asUnchecked(),
gg[].asUnchecked(),
gL.len
)
G = gL

proof.a0 = a[0]

# Deallocs
# -----------------------------------
freeHeapAligned(gg)
freeHeapAligned(gprime)
freeHeapAligned(b)
freeHeapAligned(bprime)
freeHeapAligned(aprime)

func computeChangeOfBasisFactors[F](
s: MutableView[F],
Expand Down Expand Up @@ -353,7 +360,6 @@ func ipa_verify*[N, logN: static int, EcAff, F](
let (xs, xinvs) = fs.chunk(0, 2*logN).splitHalf()
let (L, R) = ecs.chunk(0, 2*logN).splitHalf()


# [⟨ā,b̄⟩.w]G
let fs_abwg = fs.chunk(2*logN, 1)
let ecs_abwg = ecs.chunk(2*logN, 1)
Expand Down
2 changes: 1 addition & 1 deletion constantine/commitments/pedersen_commitments.nim
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func pedersen_commit*[EC, ECaff, F](
##
## Output:
## Commit(m) := ∑[mᵢ]Gᵢ
r.pedersen_commit(messages.toOpenArray(), public_generators.toOpenArray())
public_generators.toOpenArray().pedersen_commit(r, messages.toOpenArray())

func pedersen_commit*[EC, ECaff](
public_generators: openArray[ECaff],
Expand Down
6 changes: 6 additions & 0 deletions constantine/platforms/views.nim
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ func toMutableView*[T](data: ptr UncheckedArray[T], len: int): MutableView[T] {.
func toMutableView*[N: static int, T](data: ptr array[N, T]): MutableView[T] {.inline.} =
MutableView[T](View[T](data: cast[ptr UncheckedArray[T]](data), len: N))

func toMutableView*[N: static int, T](data: var array[N, T]): MutableView[T] {.inline.} =
MutableView[T](View[T](data: cast[ptr UncheckedArray[T]](data.addr), len: N))

template asView*[T](v: MutableView[T]): View[T] =
View[T](v)

func `[]`*[T](v: MutableView[T], idx: int): var T {.inline.} =
v.data[idx]
func `[]=`*[T](v: MutableView[T], idx: int, val: T) {.inline.} =
Expand Down
83 changes: 42 additions & 41 deletions tests/t_ethereum_verkle_ipa_primitives.nim
Original file line number Diff line number Diff line change
Expand Up @@ -446,55 +446,56 @@ suite "IPA proof tests":

testIPAProofInDomain()

# test "Test for IPA proof consistency":
# proc testIPAProofConsistency()=
test "Test for IPA proof consistency":
proc testIPAProofConsistency()=

# from a shared view
var opening_challenge: Fr[Banderwagon]
opening_challenge.fromInt(2101)

# from the prover's side
var testVals: array[256, int] = [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
]
var poly: PolynomialEval[256, Fr[Banderwagon]]
poly.evals.testPoly256(testVals)

# #from a shared view
# var point: Fr[Banderwagon]
# point.fromInt(2101)

# #from the prover's side
# var testVals: array[256, int] = [
# 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
# 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
# 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
# 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
# 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
# 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
# 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
# 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
# ]
# var poly: array[256, Fr[Banderwagon]]
# poly.testPoly256(testVals)

# var ipaConfig {.noInit.}: IPASettings
# ipaConfig.genIPAConfig()

# var prover_transcript {.noInit.}: sha256
# prover_transcript.initTranscript("test")

# var prover_comm: EC_P
# prover_comm.pedersen_commit(poly, ipaConfig.crs)

# var pcb {.noInit.}: array[32, byte]
# discard pcb.serialize(prover_comm)
var CRS: PolynomialEval[EthVerkleDomain, ECP_TwEdwards_Aff[Fp[Banderwagon]]]
CRS.evals.generate_random_points()

# doAssert pcb.toHex() == "0x1b9dff8f5ebbac250d291dfe90e36283a227c64b113c37f1bfb9e7a743cdb128", "Issue with computing commitment"
var domain: PolyEvalLinearDomain[EthVerkleDomain, Fr[Banderwagon]]
domain.setupLinearEvaluationDomain()

# var ipaProof1 {.noInit.}: IPAProofDeprecated
# let stat11 = ipaProof1.createIPAProof(prover_transcript, ipaConfig, prover_comm, poly, point)
# doAssert stat11 == true, "Problem creating IPA proof 1"
var tr {.noInit.}: sha256
tr.initTranscript("test")

# var lagrange_coeffs: array[256, Fr[Banderwagon]]
# ipaConfig.domain.getLagrangeBasisPolysAt(lagrange_coeffs, point)
var commitment: ECP_TwEdwards_Prj[Fp[Banderwagon]]
CRS.evals.pedersen_commit(commitment, poly.evals)
var comm: ECP_TwEdwards_Aff[Fp[Banderwagon]]
comm.affine(commitment)

# var op_point: Fr[Banderwagon]
# op_point.computeInnerProducts(lagrange_coeffs, poly)
var C {.noInit.}: array[32, byte]
C.serialize(commitment)
doAssert C.toHex() == "0x1b9dff8f5ebbac250d291dfe90e36283a227c64b113c37f1bfb9e7a743cdb128", "Issue with computing commitment"

var proof {.noInit.}: IpaProof[8, ECP_TwEdwards_Aff[Fp[Banderwagon]], Fr[Banderwagon]]
var eval_at_challenge {.noInit.}: Fr[Banderwagon]
CRS.ipa_prove(
domain, tr,
eval_at_challenge, proof,
poly, comm,
opening_challenge)

# doAssert op_point.toHex(littleEndian) == "0x4a353e70b03c89f161de002e8713beec0d740a5e20722fd5bd68b30540a33208", "Issue with computing commitment"
doAssert eval_at_challenge.toHex(littleEndian) == "0x4a353e70b03c89f161de002e8713beec0d740a5e20722fd5bd68b30540a33208", "Issue with computing commitment"

# testIPAProofConsistency()
testIPAProofConsistency()

# test "Test for IPA proof equality":
# proc testIPAProofEquality()=
Expand Down

0 comments on commit 189e2a1

Please sign in to comment.