ceremonyclient/node/execution/intrinsics/ceremony/application/multiply.go
Cassandra Heart 0cd6b41f5d
v1.2.4 (#43)
2024-02-13 01:04:56 -06:00

584 lines
14 KiB
Go

package application
import (
"encoding/binary"
"encoding/json"
"github.com/pkg/errors"
"golang.org/x/crypto/sha3"
"source.quilibrium.com/quilibrium/monorepo/nekryptology/pkg/core/curves"
bls48581 "source.quilibrium.com/quilibrium/monorepo/nekryptology/pkg/core/curves/native/bls48581"
"source.quilibrium.com/quilibrium/monorepo/nekryptology/pkg/ot/base/simplest"
"source.quilibrium.com/quilibrium/monorepo/nekryptology/pkg/ot/extension/kos"
"source.quilibrium.com/quilibrium/monorepo/nekryptology/pkg/tecdsa/dkls/v1/sign"
"source.quilibrium.com/quilibrium/monorepo/nekryptology/pkg/zkp/schnorr"
)
type MultiplyReceiverRound int
type MultiplySenderRound int
const (
MULTIPLY_RECEIVER_ROUND_UNINITIALIZED = MultiplyReceiverRound(iota)
MULTIPLY_RECEIVER_ROUND_1_COMPUTE_AND_ZKP_TO_PUBKEY
MULTIPLY_RECEIVER_ROUND_2_PAD_TRANSFER
MULTIPLY_RECEIVER_ROUND_3_VERIFY
MULTIPLY_RECEIVER_ROUND_4_MULTIPLY_INIT
MULTIPLY_RECEIVER_ROUND_5_MULTIPLY
MULTIPLY_RECEIVER_ROUND_6_DONE
)
const (
MULTIPLY_SENDER_ROUND_UNINITIALIZED = MultiplySenderRound(iota)
MULTIPLY_SENDER_ROUND_1_INITIALIZED
MULTIPLY_SENDER_ROUND_2_VERIFY_SCHNORR_AND_PAD_TRANSFER
MULTIPLY_SENDER_ROUND_3_RESPOND_TO_CHALLENGE
MULTIPLY_SENDER_ROUND_4_VERIFY
MULTIPLY_SENDER_ROUND_5_MULTIPLY
MULTIPLY_SENDER_ROUND_6_DONE
)
type Iterator interface {
Init() error
Next(message []byte) ([]byte, error)
IsDone() bool
GetPoints() []curves.Point
GetScalars() []curves.Scalar
}
type MultiplySender struct {
seed [32]byte
alphas []curves.Scalar
curve *curves.Curve
simplestReceiver *simplest.Receiver
sender []*sign.MultiplySender
step MultiplySenderRound
}
type MultiplyReceiver struct {
seed [32]byte
betas []curves.Scalar
curve *curves.Curve
simplestSender *simplest.Sender
receiver []*sign.MultiplyReceiver
step MultiplyReceiverRound
}
var _ Iterator = (*MultiplySender)(nil)
var _ Iterator = (*MultiplyReceiver)(nil)
type SchnorrProof struct {
C []byte
S []byte
Statement []byte
}
type KOSRound2Output struct {
Tau [][][]byte
}
type MultiplyRound2Output struct {
COTRound2Output *KOSRound2Output
R [][]byte
U []byte
}
func NewMultiplySender(
alphas []curves.Scalar,
curve *curves.Curve,
seed [32]byte,
) *MultiplySender {
return &MultiplySender{
seed: seed,
alphas: alphas,
curve: curve,
simplestReceiver: nil,
sender: []*sign.MultiplySender{},
step: MULTIPLY_SENDER_ROUND_UNINITIALIZED,
}
}
func NewMultiplyReceiver(
betas []curves.Scalar,
curve *curves.Curve,
seed [32]byte,
) *MultiplyReceiver {
return &MultiplyReceiver{
seed: seed,
betas: betas,
curve: curve,
simplestSender: nil,
receiver: []*sign.MultiplyReceiver{},
step: MULTIPLY_RECEIVER_ROUND_UNINITIALIZED,
}
}
func (s *MultiplySender) Init() error {
seed := sha3.Sum256(append(append([]byte{}, s.seed[:]...), []byte("OT")...))
var err error
s.simplestReceiver, err = simplest.NewReceiver(s.curve, 584, seed)
s.step = MULTIPLY_SENDER_ROUND_1_INITIALIZED
return err
}
func (r *MultiplyReceiver) Init() error {
seed := sha3.Sum256(append(append([]byte{}, r.seed[:]...), []byte("OT")...))
var err error
r.simplestSender, err = simplest.NewSender(r.curve, 584, seed)
r.step = MULTIPLY_RECEIVER_ROUND_1_COMPUTE_AND_ZKP_TO_PUBKEY
return err
}
func (s *MultiplySender) Next(message []byte) ([]byte, error) {
switch s.step {
case MULTIPLY_SENDER_ROUND_1_INITIALIZED:
s.step = MULTIPLY_SENDER_ROUND_2_VERIFY_SCHNORR_AND_PAD_TRANSFER
return nil, nil
case MULTIPLY_SENDER_ROUND_2_VERIFY_SCHNORR_AND_PAD_TRANSFER:
proof := &SchnorrProof{}
err := json.Unmarshal([]byte(message), proof)
if err != nil {
return nil, errors.Wrap(err, "next")
}
schnorrC, err := s.curve.Scalar.SetBytes(proof.C)
if err != nil {
return nil, errors.Wrap(err, "next")
}
schnorrS, err := s.curve.Scalar.SetBytes(proof.S)
if err != nil {
return nil, errors.Wrap(err, "next")
}
schnorrStatement, err := s.curve.Point.FromAffineCompressed(proof.Statement)
if err != nil {
return nil, errors.Wrap(err, "next")
}
schnorrProof := &schnorr.Proof{
C: schnorrC,
S: schnorrS,
Statement: schnorrStatement,
}
receiversMaskedChoice, err :=
s.simplestReceiver.Round2VerifySchnorrAndPadTransfer(schnorrProof)
if err != nil {
return nil, errors.Wrap(err, "next")
}
marshaledReceiversMaskedChoice, err := json.Marshal(receiversMaskedChoice)
if err != nil {
return nil, errors.Wrap(err, "next")
}
s.step = MULTIPLY_SENDER_ROUND_3_RESPOND_TO_CHALLENGE
return marshaledReceiversMaskedChoice, nil
case MULTIPLY_SENDER_ROUND_3_RESPOND_TO_CHALLENGE:
challenge := [][32]byte{}
err := json.Unmarshal([]byte(message), &challenge)
if err != nil {
return nil, errors.Wrap(err, "next")
}
challengeResponse, err := s.simplestReceiver.Round4RespondToChallenge(
challenge,
)
if err != nil {
return nil, errors.Wrap(err, "next")
}
marshaledChallengeResponse, err := json.Marshal(challengeResponse)
if err != nil {
return nil, errors.Wrap(err, "next")
}
s.step = MULTIPLY_SENDER_ROUND_4_VERIFY
return marshaledChallengeResponse, errors.Wrap(err, "next")
case MULTIPLY_SENDER_ROUND_4_VERIFY:
challengeOpenings := [][2][32]byte{}
err := json.Unmarshal([]byte(message), &challengeOpenings)
if err != nil {
return nil, errors.Wrap(err, "next")
}
err = s.simplestReceiver.Round6Verify(challengeOpenings)
if err != nil {
return nil, errors.Wrap(err, "next")
}
baseOtReceiverOutput := s.simplestReceiver.Output
for i := 0; i < len(s.alphas); i++ {
seed := sha3.Sum256(
append(
append(
append([]byte{}, s.seed[:]...),
[]byte("MUL")...,
),
binary.BigEndian.AppendUint64([]byte{}, uint64(i))...,
),
)
sender, err := sign.NewMultiplySender(
584,
160,
baseOtReceiverOutput,
s.curve,
seed,
)
if err != nil {
return nil, errors.Wrap(err, "next")
}
s.sender = append(s.sender, sender)
}
s.step = MULTIPLY_SENDER_ROUND_5_MULTIPLY
return nil, nil
case MULTIPLY_SENDER_ROUND_5_MULTIPLY:
round1Outputs := []*kos.Round1Output{}
err := json.Unmarshal([]byte(message), &round1Outputs)
if err != nil {
return nil, errors.Wrap(err, "next")
}
if len(round1Outputs) != len(s.alphas) {
return nil, errors.Wrap(errors.New("incorrect number of outputs"), "next")
}
outputs := []*MultiplyRound2Output{}
for i := 0; i < len(s.alphas); i++ {
round2Output, err := s.sender[i].Round2Multiply(
s.alphas[i],
round1Outputs[i],
)
if err != nil {
return nil, errors.Wrap(err, "next")
}
tau := [][][]byte{}
for _, t := range round2Output.COTRound2Output.Tau {
tBytes := [][]byte{}
for _, ts := range t {
tBytes = append(tBytes, ts.Bytes())
}
tau = append(tau, tBytes)
}
r := [][]byte{}
for _, rs := range round2Output.R {
r = append(r, rs.Bytes())
}
outputs = append(outputs, &MultiplyRound2Output{
COTRound2Output: &KOSRound2Output{
Tau: tau,
},
R: r,
U: round2Output.U.Bytes(),
})
}
marshaledOutputs, err := json.Marshal(outputs)
if err != nil {
return nil, errors.Wrap(err, "next")
}
s.step = MULTIPLY_SENDER_ROUND_6_DONE
return marshaledOutputs, nil
}
return nil, nil
}
func (r *MultiplyReceiver) Next(message []byte) ([]byte, error) {
switch r.step {
case MULTIPLY_RECEIVER_ROUND_1_COMPUTE_AND_ZKP_TO_PUBKEY:
proof, err := r.simplestSender.Round1ComputeAndZkpToPublicKey()
if err != nil {
return nil, errors.Wrap(err, "next")
}
schnorrProof := &SchnorrProof{
C: proof.C.Bytes(),
S: proof.S.Bytes(),
Statement: proof.Statement.ToAffineCompressed(),
}
marshaledProof, err := json.Marshal(schnorrProof)
if err != nil {
return nil, errors.Wrap(err, "next")
}
r.step = MULTIPLY_RECEIVER_ROUND_2_PAD_TRANSFER
return marshaledProof, nil
case MULTIPLY_RECEIVER_ROUND_2_PAD_TRANSFER:
receiversMaskedChoice := [][]byte{}
err := json.Unmarshal([]byte(message), &receiversMaskedChoice)
if err != nil {
return nil, errors.Wrap(err, "next")
}
challenge, err := r.simplestSender.Round3PadTransfer(receiversMaskedChoice)
if err != nil {
return nil, errors.Wrap(err, "next")
}
marshaledChallenge, err := json.Marshal(challenge)
if err != nil {
return nil, errors.Wrap(err, "next")
}
r.step = MULTIPLY_RECEIVER_ROUND_3_VERIFY
return marshaledChallenge, nil
case MULTIPLY_RECEIVER_ROUND_3_VERIFY:
challengeResponse := [][32]byte{}
err := json.Unmarshal([]byte(message), &challengeResponse)
if err != nil {
return nil, errors.Wrap(err, "next")
}
challengeOpenings, err := r.simplestSender.Round5Verify(challengeResponse)
if err != nil {
return nil, errors.Wrap(err, "next")
}
marshaledChallengeOpenings, err := json.Marshal(challengeOpenings)
if err != nil {
return nil, errors.Wrap(err, "next")
}
r.step = MULTIPLY_RECEIVER_ROUND_4_MULTIPLY_INIT
return marshaledChallengeOpenings, nil
case MULTIPLY_RECEIVER_ROUND_4_MULTIPLY_INIT:
baseOtSenderOutput := r.simplestSender.Output
outputs := []*kos.Round1Output{}
for i := 0; i < len(r.betas); i++ {
seed := sha3.Sum256(
append(
append(
append([]byte{}, r.seed[:]...),
[]byte("MUL")...,
),
binary.BigEndian.AppendUint64([]byte{}, uint64(i))...,
),
)
receiver, err := sign.NewMultiplyReceiver(
584,
160,
baseOtSenderOutput,
r.curve,
seed,
)
if err != nil {
return nil, errors.Wrap(err, "next")
}
r.receiver = append(r.receiver, receiver)
round1Output, err := r.receiver[i].Round1Initialize(r.betas[i])
if err != nil {
return nil, errors.Wrap(err, "next")
}
outputs = append(outputs, round1Output)
}
marshaledOutputs, err := json.Marshal(outputs)
if err != nil {
return nil, errors.Wrap(err, "next")
}
r.step = MULTIPLY_RECEIVER_ROUND_5_MULTIPLY
return marshaledOutputs, nil
case MULTIPLY_RECEIVER_ROUND_5_MULTIPLY:
round2Output := []*MultiplyRound2Output{}
err := json.Unmarshal([]byte(message), &round2Output)
if err != nil {
return nil, errors.Wrap(err, "next")
}
if len(round2Output) != len(r.betas) {
return nil, errors.Wrap(errors.New("incorrect number of outputs"), "next")
}
for i := 0; i < len(r.betas); i++ {
rawRound2Output := &sign.MultiplyRound2Output{
COTRound2Output: &kos.Round2Output{
Tau: [][]curves.Scalar{},
},
R: []curves.Scalar{},
U: nil,
}
for _, t := range round2Output[i].COTRound2Output.Tau {
tScalars := []curves.Scalar{}
for _, ts := range t {
sc, err := r.curve.Scalar.SetBytes(ts)
if err != nil {
return nil, errors.Wrap(err, "next")
}
tScalars = append(tScalars, sc)
}
rawRound2Output.COTRound2Output.Tau = append(
rawRound2Output.COTRound2Output.Tau,
tScalars,
)
}
for _, rs := range round2Output[i].R {
sc, err := r.curve.Scalar.SetBytes(rs)
if err != nil {
return nil, errors.Wrap(err, "next")
}
rawRound2Output.R = append(rawRound2Output.R, sc)
}
rawRound2Output.U, err = r.curve.Scalar.SetBytes(round2Output[i].U)
if err != nil {
return nil, errors.Wrap(err, "next")
}
err := r.receiver[i].Round3Multiply(rawRound2Output)
if err != nil {
return nil, errors.Wrap(err, "next")
}
}
r.step = MULTIPLY_RECEIVER_ROUND_6_DONE
return nil, nil
}
return nil, nil
}
func (s *MultiplySender) IsDone() bool {
return s.step == MULTIPLY_SENDER_ROUND_6_DONE
}
func (r *MultiplyReceiver) IsDone() bool {
return r.step == MULTIPLY_RECEIVER_ROUND_6_DONE
}
func (s *MultiplySender) GetPoints() []curves.Point {
points := []curves.Point{}
for i := 0; i < len(s.alphas); i++ {
points = append(
points,
s.curve.NewGeneratorPoint().Mul(
s.sender[i].OutputAdditiveShare,
),
)
}
return points
}
func (r *MultiplyReceiver) GetPoints() []curves.Point {
points := []curves.Point{}
for i := 0; i < len(r.betas); i++ {
points = append(
points,
r.curve.NewGeneratorPoint().Mul(
r.receiver[i].OutputAdditiveShare,
),
)
}
return points
}
func (s *MultiplySender) GetScalars() []curves.Scalar {
scalars := []curves.Scalar{}
for i := 0; i < len(s.alphas); i++ {
scalars = append(
scalars,
s.sender[i].OutputAdditiveShare,
)
}
return scalars
}
func (r *MultiplyReceiver) GetScalars() []curves.Scalar {
scalars := []curves.Scalar{}
for i := 0; i < len(r.betas); i++ {
scalars = append(
scalars,
r.receiver[i].OutputAdditiveShare,
)
}
return scalars
}
func (s *MultiplySender) GetSignatureOfProverKey(
proverKey []byte,
) ([]byte, error) {
signature := make([]byte, int(bls48581.MODBYTES)+1)
key := s.sender[0].OutputAdditiveShare.Bytes()
if bls48581.Core_Sign(signature, proverKey, key) != bls48581.BLS_OK {
return nil, errors.Wrap(
errors.New("could not sign"),
"get signature of prover key",
)
}
return signature[:], nil
}
func (r *MultiplyReceiver) GetSignatureOfProverKey(
proverKey []byte,
) ([]byte, error) {
signature := make([]byte, int(bls48581.MODBYTES)+1)
key := r.receiver[0].OutputAdditiveShare.Bytes()
if bls48581.Core_Sign(signature, proverKey, key) != bls48581.BLS_OK {
return nil, errors.Wrap(
errors.New("could not sign"),
"get signature of prover key",
)
}
return signature[:], nil
}
func SignProverKeyForCommit(
proverKey []byte,
commitKey curves.Scalar,
) ([]byte, error) {
signature := make([]byte, int(bls48581.MODBYTES)+1)
key := commitKey.Bytes()
if bls48581.Core_Sign(signature, proverKey, key) != bls48581.BLS_OK {
return nil, errors.Wrap(
errors.New("could not sign"),
"sign prover key for commit",
)
}
return signature[:], nil
}
func VerifySignatureOfProverKey(
proverKey []byte,
signature []byte,
publicPointG2 curves.Point,
) error {
w := publicPointG2.ToAffineCompressed()
if bls48581.Core_Verify(signature, proverKey, w) != bls48581.BLS_OK {
return errors.Wrap(
errors.New("could not verify"),
"verify signature of prover key",
)
}
return nil
}