sonr/crypto/bulletproof/ipp_verifier.go

210 lines
7.3 KiB
Go
Raw Normal View History

feature/1114 implement account interface (#1167) - **refactor: move session-related code to middleware package** - **refactor: update PKL build process and adjust related configurations** - **feat: integrate base.cosmos.v1 Genesis module** - **refactor: pass session context to modal rendering functions** - **refactor: move nebula package to app directory and update templ version** - **refactor: Move home section video view to dedicated directory** - **refactor: remove unused views file** - **refactor: move styles and UI components to global scope** - **refactor: Rename images.go to cdn.go** - **feat: Add Empty State Illustrations** - **refactor: Consolidate Vault Index Logic** - **fix: References to App.wasm and remove Vault Directory embedded CDN files** - **refactor: Move CDN types to Models** - **fix: Correct line numbers in templ error messages for arch_templ.go** - **refactor: use common types for peer roles** - **refactor: move common types and ORM to a shared package** - **fix: Config import dwn** - **refactor: move nebula directory to app** - **feat: Rebuild nebula** - **fix: correct file paths in panels templates** - **feat: Remove duplicate types** - **refactor: Move dwn to pkg/core** - **refactor: Binary Structure** - **feat: Introduce Crypto Pkg** - **fix: Broken Process Start** - **feat: Update pkg/* structure** - **feat: Refactor PKL Structure** - **build: update pkl build process** - **chore: Remove Empty Files** - **refactor: remove unused macaroon package** - **feat: Add WebAwesome Components** - **refactor: consolidate build and generation tasks into a single taskfile, remove redundant makefile targets** - **refactor: refactor server and move components to pkg/core/dwn** - **build: update go modules** - **refactor: move gateway logic into dedicated hway command** - **feat: Add KSS (Krawczyk-Song-Song) MPC cryptography module** - **feat: Implement MPC-based JWT signing and UCAN token generation** - **feat: add support for MPC-based JWT signing** - **feat: Implement MPC-based UCAN capabilities for smart accounts** - **feat: add address field to keyshareSource** - **feat: Add comprehensive MPC test suite for keyshares, UCAN tokens, and token attenuations** - **refactor: improve MPC keyshare management and signing process** - **feat: enhance MPC capability hierarchy documentation** - **refactor: rename GenerateKeyshares function to NewKeyshareSource for clarity** - **refactor: remove unused Ethereum address computation** - **feat: Add HasHandle and IsAuthenticated methods to HTTPContext** - **refactor: Add context.Context support to session HTTPContext** - **refactor: Resolve context interface conflicts in HTTPContext** - **feat: Add session ID context key and helper functions** - **feat: Update WebApp Page Rendering** - **refactor: Simplify context management by using single HTTPContext key** - **refactor: Simplify HTTPContext creation and context management in session middleware** - **refactor: refactor session middleware to use a single data structure** - **refactor: Simplify HTTPContext implementation and session data handling** - **refactor: Improve session context handling and prevent nil pointer errors** - **refactor: Improve session context handling with nil safety and type support** - **refactor: improve session data injection** - **feat: add full-screen modal component and update registration flow** - **chore: add .air.toml to .gitignore** - **feat: add Air to devbox and update dependencies**
2024-11-23 01:28:58 -05:00
package bulletproof
import (
"github.com/gtank/merlin"
"github.com/pkg/errors"
"github.com/onsonr/sonr/crypto/core/curves"
feature/1114 implement account interface (#1167) - **refactor: move session-related code to middleware package** - **refactor: update PKL build process and adjust related configurations** - **feat: integrate base.cosmos.v1 Genesis module** - **refactor: pass session context to modal rendering functions** - **refactor: move nebula package to app directory and update templ version** - **refactor: Move home section video view to dedicated directory** - **refactor: remove unused views file** - **refactor: move styles and UI components to global scope** - **refactor: Rename images.go to cdn.go** - **feat: Add Empty State Illustrations** - **refactor: Consolidate Vault Index Logic** - **fix: References to App.wasm and remove Vault Directory embedded CDN files** - **refactor: Move CDN types to Models** - **fix: Correct line numbers in templ error messages for arch_templ.go** - **refactor: use common types for peer roles** - **refactor: move common types and ORM to a shared package** - **fix: Config import dwn** - **refactor: move nebula directory to app** - **feat: Rebuild nebula** - **fix: correct file paths in panels templates** - **feat: Remove duplicate types** - **refactor: Move dwn to pkg/core** - **refactor: Binary Structure** - **feat: Introduce Crypto Pkg** - **fix: Broken Process Start** - **feat: Update pkg/* structure** - **feat: Refactor PKL Structure** - **build: update pkl build process** - **chore: Remove Empty Files** - **refactor: remove unused macaroon package** - **feat: Add WebAwesome Components** - **refactor: consolidate build and generation tasks into a single taskfile, remove redundant makefile targets** - **refactor: refactor server and move components to pkg/core/dwn** - **build: update go modules** - **refactor: move gateway logic into dedicated hway command** - **feat: Add KSS (Krawczyk-Song-Song) MPC cryptography module** - **feat: Implement MPC-based JWT signing and UCAN token generation** - **feat: add support for MPC-based JWT signing** - **feat: Implement MPC-based UCAN capabilities for smart accounts** - **feat: add address field to keyshareSource** - **feat: Add comprehensive MPC test suite for keyshares, UCAN tokens, and token attenuations** - **refactor: improve MPC keyshare management and signing process** - **feat: enhance MPC capability hierarchy documentation** - **refactor: rename GenerateKeyshares function to NewKeyshareSource for clarity** - **refactor: remove unused Ethereum address computation** - **feat: Add HasHandle and IsAuthenticated methods to HTTPContext** - **refactor: Add context.Context support to session HTTPContext** - **refactor: Resolve context interface conflicts in HTTPContext** - **feat: Add session ID context key and helper functions** - **feat: Update WebApp Page Rendering** - **refactor: Simplify context management by using single HTTPContext key** - **refactor: Simplify HTTPContext creation and context management in session middleware** - **refactor: refactor session middleware to use a single data structure** - **refactor: Simplify HTTPContext implementation and session data handling** - **refactor: Improve session context handling and prevent nil pointer errors** - **refactor: Improve session context handling with nil safety and type support** - **refactor: improve session data injection** - **feat: add full-screen modal component and update registration flow** - **chore: add .air.toml to .gitignore** - **feat: add Air to devbox and update dependencies**
2024-11-23 01:28:58 -05:00
)
// InnerProductVerifier is the struct used to verify inner product proofs
// It specifies which curve to use and holds precomputed generators
// See NewInnerProductProver() for prover initialization.
type InnerProductVerifier struct {
curve curves.Curve
generators ippGenerators
}
// NewInnerProductVerifier initializes a new verifier
// It uses the specified domain to generate generators for vectors of at most maxVectorLength
// A verifier can be used to verify inner product proofs for vectors of length less than or equal to maxVectorLength
// A verifier is defined by an explicit curve.
func NewInnerProductVerifier(maxVectorLength int, domain []byte, curve curves.Curve) (*InnerProductVerifier, error) {
generators, err := getGeneratorPoints(maxVectorLength, domain, curve)
if err != nil {
return nil, errors.Wrap(err, "ipp getGenerators")
}
return &InnerProductVerifier{curve: curve, generators: *generators}, nil
}
// Verify verifies the given proof inputs
// It implements the final comparison of section 3.1 on pg17 of https://eprint.iacr.org/2017/1066.pdf
func (verifier *InnerProductVerifier) Verify(capP, u curves.Point, proof *InnerProductProof, transcript *merlin.Transcript) (bool, error) {
if len(proof.capLs) != len(proof.capRs) {
return false, errors.New("ipp capLs and capRs must be same length")
}
// Generator vectors must be same length
if len(verifier.generators.G) != len(verifier.generators.H) {
return false, errors.New("ipp generator lengths of g and h must be equal")
}
// Get generators for each elem in a, b and one more for u
// len(Ls) = log n, therefore can just exponentiate
n := 1 << len(proof.capLs)
// Length of vectors must be less than the number of generators generated
if n > len(verifier.generators.G) {
return false, errors.New("ipp vector length must be less than maxVectorLength")
}
// In case where len(a) is less than number of generators precomputed by prover, trim to length
proofG := verifier.generators.G[0:n]
proofH := verifier.generators.H[0:n]
xs, err := getxs(transcript, proof.capLs, proof.capRs, verifier.curve)
if err != nil {
return false, errors.Wrap(err, "verifier getxs")
}
s, err := verifier.getsNew(xs, n)
if err != nil {
return false, errors.Wrap(err, "verifier getss")
}
lhs, err := verifier.getLHS(u, proof, proofG, proofH, s)
if err != nil {
return false, errors.Wrap(err, "verify getLHS")
}
rhs, err := verifier.getRHS(capP, proof, xs)
if err != nil {
return false, errors.Wrap(err, "verify getRHS")
}
return lhs.Equal(rhs), nil
}
// Verify verifies the given proof inputs
// It implements the final comparison of section 3.1 on pg17 of https://eprint.iacr.org/2017/1066.pdf
func (verifier *InnerProductVerifier) VerifyFromRangeProof(proofG, proofH []curves.Point, capPhmuinv, u curves.Point, tHat curves.Scalar, proof *InnerProductProof, transcript *merlin.Transcript) (bool, error) {
// Get generators for each elem in a, b and one more for u
// len(Ls) = log n, therefore can just exponentiate
n := 1 << len(proof.capLs)
xs, err := getxs(transcript, proof.capLs, proof.capRs, verifier.curve)
if err != nil {
return false, errors.Wrap(err, "verifier getxs")
}
s, err := verifier.gets(xs, n)
if err != nil {
return false, errors.Wrap(err, "verifier getss")
}
lhs, err := verifier.getLHS(u, proof, proofG, proofH, s)
if err != nil {
return false, errors.Wrap(err, "verify getLHS")
}
utHat := u.Mul(tHat)
capP := capPhmuinv.Add(utHat)
rhs, err := verifier.getRHS(capP, proof, xs)
if err != nil {
return false, errors.Wrap(err, "verify getRHS")
}
return lhs.Equal(rhs), nil
}
// getRHS gets the right hand side of the final comparison of section 3.1 on pg17.
func (*InnerProductVerifier) getRHS(capP curves.Point, proof *InnerProductProof, xs []curves.Scalar) (curves.Point, error) {
product := capP
for j, Lj := range proof.capLs {
Rj := proof.capRs[j]
xj := xs[j]
xjSquare := xj.Square()
xjSquareInv, err := xjSquare.Invert()
if err != nil {
return nil, errors.Wrap(err, "verify invert")
}
LjxjSquare := Lj.Mul(xjSquare)
RjxjSquareInv := Rj.Mul(xjSquareInv)
product = product.Add(LjxjSquare).Add(RjxjSquareInv)
}
return product, nil
}
// getLHS gets the left hand side of the final comparison of section 3.1 on pg17.
func (verifier *InnerProductVerifier) getLHS(u curves.Point, proof *InnerProductProof, g, h []curves.Point, s []curves.Scalar) (curves.Point, error) {
sInv, err := invertScalars(s)
if err != nil {
return nil, errors.Wrap(err, "verify invertScalars")
}
// g^(a*s)
as := multiplyScalarToScalarVector(proof.a, s)
gas := verifier.curve.Point.SumOfProducts(g, as)
// h^(b*s^-1)
bsInv := multiplyScalarToScalarVector(proof.b, sInv)
hbsInv := verifier.curve.Point.SumOfProducts(h, bsInv)
// u^a*b
ab := proof.a.Mul(proof.b)
uab := u.Mul(ab)
// g^(a*s) * h^(b*s^-1) * u^a*b
out := gas.Add(hbsInv).Add(uab)
return out, nil
}
// getxs calculates the x values from Ls and Rs
// Note that each x is read from the transcript, then the L and R at a certain index are written to the transcript
// This mirrors the reading of xs and writing of Ls and Rs in the prover.
func getxs(transcript *merlin.Transcript, capLs, capRs []curves.Point, curve curves.Curve) ([]curves.Scalar, error) {
xs := make([]curves.Scalar, len(capLs))
for i, capLi := range capLs {
capRi := capRs[i]
// Add the newest L and R values to transcript
transcript.AppendMessage([]byte("addRecursiveL"), capLi.ToAffineUncompressed())
transcript.AppendMessage([]byte("addRecursiveR"), capRi.ToAffineUncompressed())
// Read 64 bytes from, set to scalar
outBytes := transcript.ExtractBytes([]byte("getx"), 64)
x, err := curve.NewScalar().SetBytesWide(outBytes)
if err != nil {
return nil, errors.Wrap(err, "calcx NewScalar SetBytesWide")
}
xs[i] = x
}
return xs, nil
}
// gets calculates the vector s of values used for verification
// See the second expression of section 3.1 on pg15
// nolint
func (verifier *InnerProductVerifier) gets(xs []curves.Scalar, n int) ([]curves.Scalar, error) {
ss := make([]curves.Scalar, n)
for i := 0; i < n; i++ {
si := verifier.curve.Scalar.One()
for j, xj := range xs {
if i>>(len(xs)-j-1)&0x01 == 1 {
si = si.Mul(xj)
} else {
xjInverse, err := xj.Invert()
if err != nil {
return nil, errors.Wrap(err, "getss invert")
}
si = si.Mul(xjInverse)
}
}
ss[i] = si
}
return ss, nil
}
// getsNew calculates the vector s of values used for verification
// It provides analogous functionality as gets(), but uses a O(n) algorithm vs O(nlogn)
// The algorithm inverts all xs, then begins multiplying the inversion by the square of x elements to
// calculate all s values thus minimizing necessary inversions/ computation.
func (verifier *InnerProductVerifier) getsNew(xs []curves.Scalar, n int) ([]curves.Scalar, error) {
var err error
ss := make([]curves.Scalar, n)
// First element is all xs inverted mul'd
ss[0] = verifier.curve.Scalar.One()
for _, xj := range xs {
ss[0] = ss[0].Mul(xj)
}
ss[0], err = ss[0].Invert()
if err != nil {
return nil, errors.Wrap(err, "ipp gets inv ss0")
}
for j, xj := range xs {
xjSquared := xj.Square()
for i := 0; i < n; i += 1 << (len(xs) - j) {
ss[i+1<<(len(xs)-j-1)] = ss[i].Mul(xjSquared)
}
}
return ss, nil
}