Skip to content

Commit

Permalink
PCS: Add vector Pedersen commitments
Browse files Browse the repository at this point in the history
  • Loading branch information
mratsim committed Jun 7, 2024
1 parent 4e1ea61 commit 67da987
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 11 deletions.
56 changes: 56 additions & 0 deletions constantine/commitments/pedersen_commitments.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Constantine
# Copyright (c) 2018-2019 Status Research & Development GmbH
# Copyright (c) 2020-Present Mamy André-Ratsimbazafy
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.

import
../math/[ec_shortweierstrass, arithmetic],
../math/elliptic/ec_multi_scalar_mul

## ############################################################
##
## Pedersen Commitments
##
## ############################################################

func pedersen_commit*[EC, ECaff](
r: var EC,
messages: openArray[Fr],
public_generators: openArray[ECaff],
blinding_factor: Fr,
hiding_generator: ECaff) =
## Blinded Vector Pedersen Commitment with elliptic curves
## - messages m=(m₀,...,mₙ₋₁)
## - public generators G
## - blinding factor r
## - hiding generator H
##
## Computes: Commit(m, r) := ∑[mᵢ]Gᵢ + [r]H

# - Non-Interactive and Information-Theoretic Secure Verifiable Secret Sharing
# Torben Pryds Pedersen
# https://link.springer.com/content/pdf/10.1007/3-540-46766-1_9.pdf
#
# - https://zcash.github.io/halo2/background/groups.html#vector-pedersen-commitment
# https://eprint.iacr.org/2019/1021.pdf
# Chapter 3
#
# - High Assurance Specification of the halo2 Protocol
# https://cdck-file-uploads-global.s3.dualstack.us-west-2.amazonaws.com/zcash/original/3X/5/0/50b210737efe301239d8d774a43e1f1d6234eab9.pdf
#
# - MIT IAP, 2023.1
# https://assets.super.so/9c1ce0ba-bad4-4680-8c65-3a46532bf44a/files/61fb28e6-f2dc-420f-89e1-cc8000233a4f.pdf
#
# - https://dankradfeist.de/ethereum/2021/07/27/inner-product-arguments.html

r.multiScalarMul_reference_vartime(messages, public_generators)

# We could run the following in MSM, but that would require extra alloc and copy
var rH {.noInit.}: EC
rH.fromAffine(hiding_generator)
rH.scalarMul_vartime(blinding_factor)

r += rH
59 changes: 48 additions & 11 deletions constantine/math/elliptic/ec_multi_scalar_mul.nim
Original file line number Diff line number Diff line change
Expand Up @@ -94,15 +94,14 @@ func multiScalarMulImpl_reference_vartime[bits: static int, EC, ECaff](
buckets.freeHeap()
miniMSMs.freeHeap()

func multiScalarMul_reference_vartime*[EC, ECaff](r: var EC, coefs: openArray[BigInt], points: openArray[ECaff]) {.tags:[VarTime, HeapAlloc].} =
func multiScalarMul_reference_dispatch_vartime[bits: static int, EC, ECaff](
r: var EC,
coefs: ptr UncheckedArray[BigInt[bits]],
points: ptr UncheckedArray[ECaff],
N: int) {.tags:[VarTime, HeapAlloc].} =
## Multiscalar multiplication:
## r <- [a₀]P₀ + [a₁]P₁ + ... + [aₙ]Pₙ
debug: doAssert coefs.len == points.len

let N = points.len
let coefs = coefs.asUnchecked()
let points = points.asUnchecked()
let c = bestBucketBitSize(N, BigInt.bits, useSignedBuckets = false, useManualTuning = false)
let c = bestBucketBitSize(N, bits, useSignedBuckets = false, useManualTuning = false)

case c
of 2: multiScalarMulImpl_reference_vartime(r, coefs, points, N, c = 2)
Expand All @@ -124,6 +123,48 @@ func multiScalarMul_reference_vartime*[EC, ECaff](r: var EC, coefs: openArray[Bi
else:
unreachable()

func multiScalarMul_reference_vartime*[bits: static int, EC, ECaff](
r: var EC,
coefs: ptr UncheckedArray[BigInt[bits]],
points: ptr UncheckedArray[ECaff],
N: int) {.tags:[VarTime, HeapAlloc].} =
## Multiscalar multiplication:
## r <- [a₀]P₀ + [a₁]P₁ + ... + [aₙ]Pₙ
multiScalarMul_reference_dispatch_vartime(r, coefs, points, len)

func multiScalarMul_reference_vartime*[EC, ECaff](r: var EC, coefs: openArray[BigInt], points: openArray[ECaff]) {.tags:[VarTime, HeapAlloc].} =
## Multiscalar multiplication:
## r <- [a₀]P₀ + [a₁]P₁ + ... + [aₙ]Pₙ
debug: doAssert coefs.len == points.len
let N = points.len
multiScalarMul_reference_dispatch_vartime(r, coefs.asUnchecked(), points.asUnchecked(), N)

func multiScalarMul_reference_vartime*[F, EC, ECaff](
r: var EC,
coefs: ptr UncheckedArray[F],
points: ptr UncheckedArray[ECaff],
len: int) {.tags:[VarTime, Alloca, HeapAlloc], meter.} =
## Multiscalar multiplication:
## r <- [a₀]P₀ + [a₁]P₁ + ... + [aₙ₋₁]Pₙ₋₁
let n = cast[int](len)
let coefs_big = allocHeapArrayAligned(matchingOrderBigInt(F.C), n, alignment = 64)

for i in 0 ..< n:
coefs_big[i].fromField(coefs[i])
r.multiScalarMul_reference_vartime(coefs_big, points, n)

freeHeapAligned(coefs_big)

func multiScalarMul_reference_vartime*[EC, ECaff](
r: var EC,
coefs: openArray[Fr],
points: openArray[ECaff]) {.tags:[VarTime, Alloca, HeapAlloc], inline.} =
## Multiscalar multiplication:
## r <- [a₀]P₀ + [a₁]P₁ + ... + [aₙ₋₁]Pₙ₋₁
debug: doAssert coefs.len == points.len
let N = points.len
multiScalarMul_reference_vartime(r, coefs.asUnchecked(), points.asUnchecked(), N)

# ########################################################### #
# #
# Multi Scalar Multiplication #
Expand Down Expand Up @@ -487,10 +528,8 @@ func multiScalarMul_vartime*[bits: static int, EC, ECaff](
points: openArray[ECaff]) {.tags:[VarTime, Alloca, HeapAlloc], meter.} =
## Multiscalar multiplication:
## r <- [a₀]P₀ + [a₁]P₁ + ... + [aₙ₋₁]Pₙ₋₁

debug: doAssert coefs.len == points.len
let N = points.len

multiScalarMul_dispatch_vartime(r, coefs.asUnchecked(), points.asUnchecked(), N)

func multiScalarMul_vartime*[F, EC, ECaff](
Expand All @@ -516,8 +555,6 @@ func multiScalarMul_vartime*[EC, ECaff](
points: openArray[ECaff]) {.tags:[VarTime, Alloca, HeapAlloc], inline.} =
## Multiscalar multiplication:
## r <- [a₀]P₀ + [a₁]P₁ + ... + [aₙ₋₁]Pₙ₋₁

debug: doAssert coefs.len == points.len
let N = points.len

multiScalarMul_vartime(r, coefs.asUnchecked(), points.asUnchecked(), N)

0 comments on commit 67da987

Please sign in to comment.