sonr/pkg/crypto/sharing/v1/pedersen.go
Prad Nukala 89989fa102
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

175 lines
4.4 KiB
Go
Executable File

//
// Copyright Coinbase, Inc. All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//
package v1
import (
crand "crypto/rand"
"encoding/binary"
"fmt"
"math/big"
"github.com/onsonr/sonr/pkg/crypto/core/curves"
"github.com/onsonr/sonr/pkg/crypto/internal"
)
// Pedersen Verifiable Secret Sharing Scheme
type Pedersen struct {
threshold, limit uint32
generator *curves.EcPoint
}
// PedersenResult contains all the data from calling Split
type PedersenResult struct {
Blinding *big.Int
BlindingShares, SecretShares []*ShamirShare
BlindedVerifiers []*ShareVerifier
Verifiers []*ShareVerifier
}
// NewPedersen creates a new pedersen VSS
func NewPedersen(threshold, limit uint32, generator *curves.EcPoint) (*Pedersen, error) {
if limit < threshold {
return nil, fmt.Errorf("limit cannot be less than threshold")
}
if threshold < 2 {
return nil, fmt.Errorf("threshold must be at least 2")
}
if generator == nil {
return nil, internal.ErrNilArguments
}
if generator.IsIdentity() {
return nil, fmt.Errorf("generator point cannot be at infinity")
}
if !generator.IsOnCurve() {
return nil, fmt.Errorf("generator point must be on the curve")
}
return &Pedersen{
threshold, limit, generator,
}, nil
}
// Split creates the verifiers, blinding and shares
func (pd Pedersen) Split(secret []byte) (*PedersenResult, error) {
// generate a random blinding factor
blinding, err := crand.Int(crand.Reader, pd.generator.Curve.Params().N)
if err != nil {
return nil, err
}
field := curves.NewField(pd.generator.Curve.Params().N)
shamir := Shamir{pd.threshold, pd.limit, field}
// split the secret into shares
shares, polySecret, err := shamir.GetSharesAndPolynomial(secret)
if err != nil {
return nil, err
}
// split the blinding into shares
blindingShares, polyBlinding, err := shamir.GetSharesAndPolynomial(blinding.Bytes())
if err != nil {
return nil, err
}
// Generate the verifiable commitments to the polynomial for the shares
blindedverifiers := make([]*ShareVerifier, pd.threshold)
verifiers := make([]*ShareVerifier, pd.threshold)
// ({p0 * G + b0 * H}, ...,{pt * G + bt * H})
for i, c := range polySecret.Coefficients {
s, err := curves.NewScalarBaseMult(pd.generator.Curve, c.Value)
if err != nil {
return nil, err
}
b, err := pd.generator.ScalarMult(polyBlinding.Coefficients[i].Value)
if err != nil {
return nil, err
}
bv, err := s.Add(b)
if err != nil {
return nil, err
}
blindedverifiers[i] = bv
verifiers[i] = s
}
return &PedersenResult{
blinding, blindingShares, shares, blindedverifiers, verifiers,
}, nil
}
// Combine recreates the original secret from the shares
func (pd Pedersen) Combine(shares ...*ShamirShare) ([]byte, error) {
field := curves.NewField(pd.generator.Curve.Params().N)
shamir := Shamir{pd.threshold, pd.limit, field}
return shamir.Combine(shares...)
}
// Verify checks a share for validity
func (pd Pedersen) Verify(share *ShamirShare, blinding *ShamirShare, blindedverifiers []*ShareVerifier) (bool, error) {
if len(blindedverifiers) < int(pd.threshold) {
return false, fmt.Errorf("not enough blindedverifiers to check")
}
field := curves.NewField(pd.generator.Curve.Params().N)
xBytes := make([]byte, 4)
binary.BigEndian.PutUint32(xBytes, share.Identifier)
x := field.ElementFromBytes(xBytes)
i := share.Value.Modulus.One()
// c_0
rhs := blindedverifiers[0]
// Compute the sum of products
// c_0 * c_1^i * c_2^{i^2} * c_3^{i^3} ... c_t^{i_t}
for j := 1; j < len(blindedverifiers); j++ {
// i *= x
i = i.Mul(x)
c, err := blindedverifiers[j].ScalarMult(i.Value)
if err != nil {
return false, err
}
// ... * c_j^{i^j}
rhs, err = rhs.Add(c)
if err != nil {
return false, err
}
}
lhs, err := curves.NewScalarBaseMult(pd.generator.Curve, share.Value.Value)
if err != nil {
return false, err
}
tmp, err := pd.generator.ScalarMult(blinding.Value.Value)
if err != nil {
return false, err
}
lhs, err = lhs.Add(tmp)
if err != nil {
return false, err
}
// Check if lhs == rhs
return lhs.Equals(rhs), nil
}
// K256GeneratorFromHashedBytes computes a generator whose discrete log is unknown
// from a bytes sequence
func K256GeneratorFromHashedBytes(bytes []byte) (x, y *big.Int, err error) {
pt := new(curves.PointK256).Hash(bytes)
p, _ := pt.(*curves.PointK256)
x = p.X().BigInt()
y = p.Y().BigInt()
err = nil
return
}